From 827d5b5a1fd0468b743c975020f9335c8f040f1b Mon Sep 17 00:00:00 2001 From: miod Date: Wed, 1 Feb 2023 20:56:23 +0000 Subject: [PATCH] Despite only testing the low-order bit of its operand, the blbc and blbs 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 | 10 -------- gnu/usr.bin/gcc/gcc/config/vax/vax.md | 35 +++------------------------ 2 files changed, 4 insertions(+), 41 deletions(-) diff --git a/gnu/usr.bin/gcc/gcc/config/vax/vax.h b/gnu/usr.bin/gcc/gcc/config/vax/vax.h index 8d36e2cc355..0c6166c4360 100644 --- a/gnu/usr.bin/gcc/gcc/config/vax/vax.h +++ b/gnu/usr.bin/gcc/gcc/config/vax/vax.h @@ -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 diff --git a/gnu/usr.bin/gcc/gcc/config/vax/vax.md b/gnu/usr.bin/gcc/gcc/config/vax/vax.md index 4a4f4d23e88..d57bd4785a7 100644 --- a/gnu/usr.bin/gcc/gcc/config/vax/vax.md +++ b/gnu/usr.bin/gcc/gcc/config/vax/vax.md @@ -1646,37 +1646,10 @@ "j%C0 %l1") ; %C0 negates condition ;; 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) -- 2.20.1