Despite only testing the low-order bit of its operand, the blbc and blbs
authormiod <miod@openbsd.org>
Wed, 1 Feb 2023 20:56:23 +0000 (20:56 +0000)
committermiod <miod@openbsd.org>
Wed, 1 Feb 2023 20:56:23 +0000 (20:56 +0000)
instructions always fetch a 32-bit word when operand is a memory address.
This works unless the address is within the last 3 bytes of a page, with
the next page being invalid, something which can happen with small malloc'ed
structures (I'm looking at you, perl).

Work around the problem by requiring a register operand in all cases; the
register load will be a zero-extension load of the right width.

This is my entry into the "fix a 30-year old bug" contest of 2023.

gnu/usr.bin/gcc/gcc/config/vax/vax.h
gnu/usr.bin/gcc/gcc/config/vax/vax.md

index 8d36e2c..0c6166c 100644 (file)
@@ -322,16 +322,6 @@ enum reg_class { NO_REGS, ALL_REGS, LIM_REG_CLASSES };
                 || (VALUE) == CONST0_RTX (SFmode))     \
    : 0)
 
-/* Optional extra constraints for this machine.
-
-   For the VAX, `Q' means that OP is a MEM that does not have a mode-dependent
-   address.  */
-
-#define EXTRA_CONSTRAINT(OP, C) \
-  ((C) == 'Q'                                                          \
-   ? GET_CODE (OP) == MEM && ! mode_dependent_address_p (XEXP (OP, 0)) \
-   : 0)
-
 /* Given an rtx X being reloaded into a reg required to be
    in class CLASS, return the class of reg to actually use.
    In general this is just CLASS; but on some machines
index 4a4f4d2..d57bd47 100644 (file)
   "j%C0 %l1") ; %C0 negates condition
 \f
 ;; Recognize jbs, jlbs, jbc and jlbc instructions.  Note that the operand
-;; of jlbs and jlbc insns are SImode in the hardware.  However, if it is
-;; memory, we use QImode in the insn.  So we can't use those instructions
-;; for mode-dependent addresses.
-
-(define_insn ""
-  [(set (pc)
-       (if_then_else
-        (ne (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
-                             (const_int 1)
-                             (match_operand:SI 1 "general_operand" "I,g"))
-            (const_int 0))
-        (label_ref (match_operand 2 "" ""))
-        (pc)))]
-  ""
-  "@
-   jlbs %0,%l2
-   jbs %1,%0,%l2")
-
-(define_insn ""
-  [(set (pc)
-       (if_then_else
-        (eq (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,g")
-                             (const_int 1)
-                             (match_operand:SI 1 "general_operand" "I,g"))
-            (const_int 0))
-        (label_ref (match_operand 2 "" ""))
-        (pc)))]
-  ""
-  "@
-   jlbc %0,%l2
-   jbc %1,%0,%l2")
+;; of jlbs and jlbc insns are SImode in the hardware.  Thus, if it is
+;; memory, we can only use SImode in the insn.  By only allowing
+;; register_operand here, we force a (possible zero-extended) load into a
+;; register, regardless of the actual mode of the memory operand.
 
 (define_insn ""
   [(set (pc)