* Re: [RFC][PATCH] Support multiple variants of memory addresses
@ 2002-08-14 3:15 Ulrich Weigand
0 siblings, 0 replies; 3+ messages in thread
From: Ulrich Weigand @ 2002-08-14 3:15 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches, Hartmut Penner
Richard Henderson wrote:
>Looks ok to me.
Great! I've now committed the patch, together with a s390 backend patch
that starts making use of the new features. At this point, the use is
rather minimal; mostly the ugly (and strictly speaking, incorrect) 'Qo'
constraint combinations we had to use can now be replaced by just 'Q'.
Backend patches making more extensive use of EXTRA_MEMORY_CONSTRAINT
and EXTRA_ADDRESS_CONSTRAINT will follow.
For reference, I've appended the complete patch I've committed, including
the parts I had already posted. With this patch applied, I've successfully
completed bootstrap and regression tests (and glibc build / test) on both
s390-ibm-linux and s390x-ibm-linux.
ChangeLog:
* reload.c (find_reloads): Handle constraint letters marked by
EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
(alternative_allows_memconst): Likewise.
* reload1.c (maybe_fix_stack_asms): Likewise.
* recog.c (asm_operand_ok, preprocess_constraints,
constrain_operands): Likewise.
* regclass.c (record_operand_costs, record_reg_classes): Likewise.
* local-alloc.c (block_alloc, requires_inout): Likewise.
* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
* defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
(EXTRA_ADDRESS_CONSTRAINT): Likewise.
* doc/tm.texi: Document these two new target macros.
* config/s390/s390.c (s390_expand_plus_operand): Accept already
valid operands.
(q_constraint): New function.
config/s390/s390-protos.h (q_constraint): Declare it.
config/s390/s390.h (EXTRA_CONSTRAINT): Use it.
(EXTRA_MEMORY_CONSTRAINT): New macro.
* config/s390/s390.md: Throughout the machine description,
replace all instances of the constraint combinations 'Qo'
or 'oQ' with simply 'Q'.
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.87
diff -c -p -r1.87 defaults.h
*** gcc/defaults.h 31 Jul 2002 02:10:04 -0000 1.87
--- gcc/defaults.h 14 Aug 2002 09:46:02 -0000
*************** You Lose! You must define PREFERRED_DEB
*** 590,593 ****
--- 590,605 ----
#define DEFAULT_USE_CXA_ATEXIT 0
#endif
+ /* Determine whether extra constraint letter should be handled
+ via address reload (like 'o'). */
+ #ifndef EXTRA_MEMORY_CONSTRAINT
+ #define EXTRA_MEMORY_CONSTRAINT(C) 0
+ #endif
+
+ /* Determine whether extra constraint letter should be handled
+ as an address (like 'p'). */
+ #ifndef EXTRA_ADDRESS_CONSTRAINT
+ #define EXTRA_ADDRESS_CONSTRAINT(C) 0
+ #endif
+
#endif /* ! GCC_DEFAULTS_H */
Index: gcc/local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.109
diff -c -p -r1.109 local-alloc.c
*** gcc/local-alloc.c 30 May 2002 20:55:09 -0000 1.109
--- gcc/local-alloc.c 14 Aug 2002 09:46:04 -0000
*************** block_alloc (b)
*** 1342,1348 ****
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
! if (recog_data.constraints[i][0] == 'p')
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
--- 1342,1349 ----
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
! if (recog_data.constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0]))
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
*************** requires_inout (p)
*** 2472,2478 ****
break;
default:
! if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
break;
/* FALLTHRU */
case 'p':
--- 2473,2480 ----
break;
default:
! if (REG_CLASS_FROM_LETTER (c) == NO_REGS
! && !EXTRA_ADDRESS_CONSTRAINT (c))
break;
/* FALLTHRU */
case 'p':
Index: gcc/recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.162
diff -c -p -r1.162 recog.c
*** gcc/recog.c 23 Jul 2002 20:50:59 -0000 1.162
--- gcc/recog.c 14 Aug 2002 09:46:06 -0000
*************** asm_operand_ok (op, constraint)
*** 1848,1853 ****
--- 1848,1865 ----
#ifdef EXTRA_CONSTRAINT
if (EXTRA_CONSTRAINT (op, c))
return 1;
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every memory operand can be reloaded to fit. */
+ if (memory_operand (op, VOIDmode))
+ return 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ /* Every address operand can be reloaded to fit. */
+ if (address_operand (op, VOIDmode))
+ return 1;
+ }
#endif
break;
}
*************** preprocess_constraints ()
*** 2287,2292 ****
--- 2299,2317 ----
break;
default:
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ op_alt[j].memory_ok = 1;
+ break;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ op_alt[j].is_address = 1;
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ break;
+ }
+
op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)];
break;
}
*************** constrain_operands (strict)
*** 2600,2605 ****
--- 2625,2652 ----
#ifdef EXTRA_CONSTRAINT
else if (EXTRA_CONSTRAINT (op, c))
win = 1;
+
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every memory operand can be reloaded to fit,
+ so copy the condition from the 'm' case. */
+ if (GET_CODE (op) == MEM
+ /* Before reload, accept what reload can turn into mem. */
+ || (strict < 0 && CONSTANT_P (op))
+ /* During reload, accept a pseudo */
+ || (reload_in_progress && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+ win = 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ /* Every address operand can be reloaded to fit,
+ so copy the condition from the 'p' case. */
+ if (strict <= 0
+ || (strict_memory_address_p (recog_data.operand_mode[opno],
+ op)))
+ win = 1;
+ }
#endif
break;
}
Index: gcc/regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.154
diff -c -p -r1.154 regclass.c
*** gcc/regclass.c 23 Jul 2002 20:50:59 -0000 1.154
--- gcc/regclass.c 14 Aug 2002 09:46:11 -0000
*************** record_operand_costs (insn, op_costs, re
*** 1007,1013 ****
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
! else if (constraints[i][0] == 'p')
record_address_regs (recog_data.operand[i],
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
}
--- 1007,1014 ----
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
! else if (constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
record_address_regs (recog_data.operand[i],
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
}
*************** record_reg_classes (n_alts, n_ops, ops,
*** 1709,1714 ****
--- 1710,1736 ----
#ifdef EXTRA_CONSTRAINT
else if (EXTRA_CONSTRAINT (op, c))
win = 1;
+
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every MEM can be reloaded to fit. */
+ allows_mem[i] = 1;
+ if (GET_CODE (op) == MEM)
+ win = 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (op))
+ {
+ /* Every address can be reloaded to fit. */
+ allows_addr = 1;
+ if (address_operand (op, GET_MODE (op)))
+ win = 1;
+ /* We know this operand is an address, so we want it to be
+ allocated to a register that can be the base of an
+ address, ie BASE_REG_CLASS. */
+ classes[i]
+ = reg_class_subunion[(int) classes[i]]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ }
#endif
break;
}
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.187
diff -c -p -r1.187 reload.c
*** gcc/reload.c 23 Jul 2002 20:51:00 -0000 1.187
--- gcc/reload.c 14 Aug 2002 09:46:17 -0000
*************** find_reloads (insn, replace, ind_levels,
*** 2641,2647 ****
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
! else if (constraints[i][0] == 'p')
{
find_reloads_address (VOIDmode, (rtx*) 0,
recog_data.operand[i],
--- 2641,2648 ----
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
! else if (constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
{
find_reloads_address (VOIDmode, (rtx*) 0,
recog_data.operand[i],
*************** find_reloads (insn, replace, ind_levels,
*** 3222,3227 ****
--- 3223,3271 ----
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
{
#ifdef EXTRA_CONSTRAINT
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ if (force_reload)
+ break;
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+ /* If the address was already reloaded,
+ we win as well. */
+ if (GET_CODE (operand) == MEM && address_reloaded[i])
+ win = 1;
+ /* Likewise if the address will be reloaded because
+ reg_equiv_address is nonzero. For reg_equiv_mem
+ we have to check. */
+ if (GET_CODE (operand) == REG
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber[REGNO (operand)] < 0
+ && ((reg_equiv_mem[REGNO (operand)] != 0
+ && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
+ || (reg_equiv_address[REGNO (operand)] != 0)))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ constants via force_const_mem, and other
+ MEMs by reloading the address like for 'o'. */
+ if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+ || GET_CODE (operand) == MEM)
+ badop = 0;
+ constmemok = 1;
+ offmemok = 1;
+ break;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ the address into a base register. */
+ this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
+ badop = 0;
+ break;
+ }
+
if (EXTRA_CONSTRAINT (operand, c))
win = 1;
#endif
*************** alternative_allows_memconst (constraint,
*** 4291,4297 ****
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
while ((c = *constraint++) && c != ',' && c != '#')
! if (c == 'm' || c == 'o')
return 1;
return 0;
}
--- 4335,4341 ----
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
while ((c = *constraint++) && c != ',' && c != '#')
! if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
return 1;
return 0;
}
Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.351
diff -c -p -r1.351 reload1.c
*** gcc/reload1.c 30 Jul 2002 16:42:05 -0000 1.351
--- gcc/reload1.c 14 Aug 2002 09:46:21 -0000
*************** maybe_fix_stack_asms ()
*** 1380,1387 ****
break;
default:
! cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
!
}
}
}
--- 1380,1391 ----
break;
default:
! if (EXTRA_ADDRESS_CONSTRAINT (c))
! cls = (int) reg_class_subunion[cls]
! [(int) MODE_BASE_REG_CLASS (VOIDmode)];
! else
! cls = (int) reg_class_subunion[cls]
! [(int) REG_CLASS_FROM_LETTER (c)];
}
}
}
Index: gcc/stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.268
diff -c -p -r1.268 stmt.c
*** gcc/stmt.c 5 Aug 2002 18:46:33 -0000 1.268
--- gcc/stmt.c 14 Aug 2002 09:46:26 -0000
*************** parse_output_constraint (constraint_p, o
*** 1252,1257 ****
--- 1252,1261 ----
if (REG_CLASS_FROM_LETTER (*p) != NO_REGS)
*allows_reg = true;
#ifdef EXTRA_CONSTRAINT
+ else if (EXTRA_ADDRESS_CONSTRAINT (*p))
+ *allows_reg = true;
+ else if (EXTRA_MEMORY_CONSTRAINT (*p))
+ *allows_mem = true;
else
{
/* Otherwise we can't assume anything about the nature of
*************** parse_input_constraint (constraint_p, in
*** 1377,1382 ****
--- 1381,1390 ----
if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
*allows_reg = true;
#ifdef EXTRA_CONSTRAINT
+ else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j]))
+ *allows_reg = true;
+ else if (EXTRA_MEMORY_CONSTRAINT (constraint[j]))
+ *allows_mem = true;
else
{
/* Otherwise we can't assume anything about the nature of
Index: gcc/config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.10
diff -c -p -r1.10 s390-protos.h
*** gcc/config/s390/s390-protos.h 13 Aug 2002 16:02:52 -0000 1.10
--- gcc/config/s390/s390-protos.h 14 Aug 2002 09:46:28 -0000
*************** extern void s390_emit_epilogue PARAMS ((
*** 31,36 ****
--- 31,37 ----
extern void s390_function_profiler PARAMS ((FILE *, int));
#ifdef RTX_CODE
+ extern int q_constraint PARAMS ((rtx));
extern int const0_operand PARAMS ((rtx, enum machine_mode));
extern int consttable_operand PARAMS ((rtx, enum machine_mode));
extern int larl_operand PARAMS ((rtx, enum machine_mode));
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.45
diff -c -p -r1.45 s390.c
*** gcc/config/s390/s390.c 13 Aug 2002 16:02:52 -0000 1.45
--- gcc/config/s390/s390.c 14 Aug 2002 09:46:30 -0000
*************** s_imm_operand (op, mode)
*** 995,1000 ****
--- 995,1022 ----
return general_s_operand (op, mode, 1);
}
+ /* Return true if OP is a valid operand for a 'Q' constraint.
+ This differs from s_operand in that only memory operands
+ without index register are accepted, nothing else. */
+
+ int
+ q_constraint (op)
+ register rtx op;
+ {
+ struct s390_address addr;
+
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ if (!s390_decompose_address (XEXP (op, 0), &addr, FALSE))
+ return 0;
+
+ if (addr.indx)
+ return 0;
+
+ return 1;
+ }
+
/* Return true if OP is a valid operand for the BRAS instruction.
OP is the current operation.
MODE is the current operation mode. */
*************** s390_expand_plus_operand (target, src, s
*** 1385,1390 ****
--- 1407,1421 ----
float registers occur in an address. */
sum1 = find_replacement (&XEXP (src, 0));
sum2 = find_replacement (&XEXP (src, 1));
+
+ /* Accept already valid addresses. */
+ src = gen_rtx_PLUS (Pmode, sum1, sum2);
+ if (s390_decompose_address (src, NULL, 1))
+ {
+ src = legitimize_la_operand (src);
+ emit_insn (gen_rtx_SET (VOIDmode, target, src));
+ return;
+ }
/* If one of the two operands is equal to the target,
make it the first one. If one is a constant, make
Index: gcc/config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.39
diff -c -p -r1.39 s390.h
*** gcc/config/s390/s390.h 16 Jul 2002 20:59:04 -0000 1.39
--- gcc/config/s390/s390.h 14 Aug 2002 09:46:31 -0000
*************** extern const enum reg_class regclass_map
*** 533,540 ****
/* 'Q' means a memory-reference for a S-type operand. */
#define EXTRA_CONSTRAINT(OP, C) \
! ((C) == 'Q' ? s_operand (OP, GET_MODE (OP)) : \
(C) == 'S' ? larl_operand (OP, GET_MODE (OP)) : 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;
--- 533,542 ----
/* 'Q' means a memory-reference for a S-type operand. */
#define EXTRA_CONSTRAINT(OP, C) \
! ((C) == 'Q' ? q_constraint (OP) : \
(C) == 'S' ? larl_operand (OP, GET_MODE (OP)) : 0)
+
+ #define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')
/* 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;
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.23
diff -c -p -r1.23 s390.md
*** gcc/config/s390/s390.md 13 Aug 2002 16:02:52 -0000 1.23
--- gcc/config/s390/s390.md 14 Aug 2002 09:46:36 -0000
***************
*** 278,284 ****
(define_insn "*tmqi_ext"
[(set (reg 33)
! (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(const_int 0)))]
--- 278,284 ----
(define_insn "*tmqi_ext"
[(set (reg 33)
! (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Q")
(match_operand:SI 1 "const_int_operand" "n")
(match_operand:SI 2 "const_int_operand" "n"))
(const_int 0)))]
***************
*** 345,351 ****
(define_insn "*tmdi_mem"
[(set (reg 33)
! (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
(match_operand:DI 1 "immediate_operand" "n"))
(match_operand:DI 2 "immediate_operand" "n")))]
"TARGET_64BIT
--- 345,351 ----
(define_insn "*tmdi_mem"
[(set (reg 33)
! (compare (and:DI (match_operand:DI 0 "s_operand" "%Q")
(match_operand:DI 1 "immediate_operand" "n"))
(match_operand:DI 2 "immediate_operand" "n")))]
"TARGET_64BIT
***************
*** 365,371 ****
(define_insn "*tmsi_mem"
[(set (reg 33)
! (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 365,371 ----
(define_insn "*tmsi_mem"
[(set (reg 33)
! (compare (and:SI (match_operand:SI 0 "s_operand" "%Q")
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 384,390 ****
(define_insn "*tmhi_mem"
[(set (reg 33)
! (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 384,390 ----
(define_insn "*tmhi_mem"
[(set (reg 33)
! (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Q") 0)
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 403,409 ****
(define_insn "*tmqi_mem"
[(set (reg 33)
! (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
--- 403,409 ----
(define_insn "*tmqi_mem"
[(set (reg 33)
! (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Q") 0)
(match_operand:SI 1 "immediate_operand" "n"))
(match_operand:SI 2 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
***************
*** 502,508 ****
(define_insn "*tsthi"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "Qo")
(match_operand:HI 1 "const0_operand" "")))
(set (match_operand:HI 2 "register_operand" "=d")
(match_dup 0))]
--- 502,508 ----
(define_insn "*tsthi"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "Q")
(match_operand:HI 1 "const0_operand" "")))
(set (match_operand:HI 2 "register_operand" "=d")
(match_dup 0))]
***************
*** 513,519 ****
(define_insn "*tsthi_cconly"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "Qo")
(match_operand:HI 1 "const0_operand" "")))
(clobber (match_scratch:HI 2 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
--- 513,519 ----
(define_insn "*tsthi_cconly"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "Q")
(match_operand:HI 1 "const0_operand" "")))
(clobber (match_scratch:HI 2 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
***************
*** 523,529 ****
(define_insn "*tstqi"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Qo")
(match_operand:QI 1 "const0_operand" "")))
(set (match_operand:QI 2 "register_operand" "=d")
(match_dup 0))]
--- 523,529 ----
(define_insn "*tstqi"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Q")
(match_operand:QI 1 "const0_operand" "")))
(set (match_operand:QI 2 "register_operand" "=d")
(match_dup 0))]
***************
*** 534,540 ****
(define_insn "*tstqi_cconly"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Qo")
(match_operand:QI 1 "const0_operand" "")))
(clobber (match_scratch:QI 2 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
--- 534,540 ----
(define_insn "*tstqi_cconly"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Q")
(match_operand:QI 1 "const0_operand" "")))
(clobber (match_scratch:QI 2 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
***************
*** 628,634 ****
(define_insn "*cmphi_ccu"
[(set (reg 33)
(compare (match_operand:HI 0 "register_operand" "d")
! (match_operand:HI 1 "s_imm_operand" "Qo")))]
"s390_match_ccmode(insn, CCUmode)"
"clm\\t%0,3,%1"
[(set_attr "op_type" "RS")
--- 628,634 ----
(define_insn "*cmphi_ccu"
[(set (reg 33)
(compare (match_operand:HI 0 "register_operand" "d")
! (match_operand:HI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clm\\t%0,3,%1"
[(set_attr "op_type" "RS")
***************
*** 637,643 ****
(define_insn "*cmpqi_ccu"
[(set (reg 33)
(compare (match_operand:QI 0 "register_operand" "d")
! (match_operand:QI 1 "s_imm_operand" "Qo")))]
"s390_match_ccmode(insn, CCUmode)"
"clm\\t%0,1,%1"
[(set_attr "op_type" "RS")
--- 637,643 ----
(define_insn "*cmpqi_ccu"
[(set (reg 33)
(compare (match_operand:QI 0 "register_operand" "d")
! (match_operand:QI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clm\\t%0,1,%1"
[(set_attr "op_type" "RS")
***************
*** 645,651 ****
(define_insn "*cli"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Qo")
(match_operand:QI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, CCUmode)"
"cli\\t%0,%b1"
--- 645,651 ----
(define_insn "*cli"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Q")
(match_operand:QI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, CCUmode)"
"cli\\t%0,%b1"
***************
*** 654,661 ****
(define_insn "*cmpdi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:DI 0 "s_operand" "oQ")
! (match_operand:DI 1 "s_imm_operand" "oQ")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
--- 654,661 ----
(define_insn "*cmpdi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:DI 0 "s_operand" "Q")
! (match_operand:DI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 663,670 ****
(define_insn "*cmpsi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:SI 0 "s_operand" "oQ")
! (match_operand:SI 1 "s_imm_operand" "oQ")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
--- 663,670 ----
(define_insn "*cmpsi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:SI 0 "s_operand" "Q")
! (match_operand:SI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 672,679 ****
(define_insn "*cmphi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "oQ")
! (match_operand:HI 1 "s_imm_operand" "oQ")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(2,%R0),%1"
[(set_attr "op_type" "SS")
--- 672,679 ----
(define_insn "*cmphi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:HI 0 "s_operand" "Q")
! (match_operand:HI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(2,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 681,688 ****
(define_insn "*cmpqi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "oQ")
! (match_operand:QI 1 "s_imm_operand" "oQ")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(1,%R0),%1"
[(set_attr "op_type" "SS")
--- 681,688 ----
(define_insn "*cmpqi_ccu_mem"
[(set (reg 33)
! (compare (match_operand:QI 0 "s_operand" "Q")
! (match_operand:QI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
"clc\\t%O0(1,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 780,787 ****
;
(define_insn "*movti_ss"
! [(set (match_operand:TI 0 "s_operand" "=Qo")
! (match_operand:TI 1 "s_imm_operand" "Qo"))]
""
"mvc\\t%O0(16,%R0),%1"
[(set_attr "op_type" "SS")
--- 780,787 ----
;
(define_insn "*movti_ss"
! [(set (match_operand:TI 0 "s_operand" "=Q")
! (match_operand:TI 1 "s_imm_operand" "Q"))]
""
"mvc\\t%O0(16,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 914,921 ****
(set_attr "type" "la")])
(define_insn "*movdi_ss"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
! (match_operand:DI 1 "s_imm_operand" "Qo"))]
""
"mvc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
--- 914,921 ----
(set_attr "type" "la")])
(define_insn "*movdi_ss"
! [(set (match_operand:DI 0 "s_operand" "=Q")
! (match_operand:DI 1 "s_imm_operand" "Q"))]
""
"mvc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 1067,1074 ****
[(set_attr "op_type" "RI")])
(define_insn "*movsi_ss"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
! (match_operand:SI 1 "s_imm_operand" "Qo"))]
""
"mvc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
--- 1067,1074 ----
[(set_attr "op_type" "RI")])
(define_insn "*movsi_ss"
! [(set (match_operand:SI 0 "s_operand" "=Q")
! (match_operand:SI 1 "s_imm_operand" "Q"))]
""
"mvc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 1156,1162 ****
(define_insn "*movstricthi"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
! (match_operand:HI 1 "s_imm_operand" "Qo"))
(clobber (reg:CC 33))]
""
"icm\\t%0,3,%1"
--- 1156,1162 ----
(define_insn "*movstricthi"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
! (match_operand:HI 1 "s_imm_operand" "Q"))
(clobber (reg:CC 33))]
""
"icm\\t%0,3,%1"
***************
*** 1197,1204 ****
}")
(define_insn "*movdf_ss"
! [(set (match_operand:DF 0 "s_operand" "=Qo")
! (match_operand:DF 1 "s_imm_operand" "Qo"))]
""
"mvc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
--- 1197,1204 ----
}")
(define_insn "*movdf_ss"
! [(set (match_operand:DF 0 "s_operand" "=Q")
! (match_operand:DF 1 "s_imm_operand" "Q"))]
""
"mvc\\t%O0(8,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 1300,1307 ****
}")
(define_insn "*movsf_ss"
! [(set (match_operand:SF 0 "s_operand" "=Qo")
! (match_operand:SF 1 "s_imm_operand" "Qo"))]
""
"mvc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
--- 1300,1307 ----
}")
(define_insn "*movsf_ss"
! [(set (match_operand:SF 0 "s_operand" "=Q")
! (match_operand:SF 1 "s_imm_operand" "Q"))]
""
"mvc\\t%O0(4,%R0),%1"
[(set_attr "op_type" "SS")
***************
*** 1388,1394 ****
(define_insn "*load_multiple_di"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:DI 1 "register_operand" "=r")
! (match_operand:DI 2 "s_operand" "oQ"))])]
""
"*
{
--- 1388,1394 ----
(define_insn "*load_multiple_di"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:DI 1 "register_operand" "=r")
! (match_operand:DI 2 "s_operand" "Q"))])]
""
"*
{
***************
*** 1407,1413 ****
(define_insn "*load_multiple_si"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "register_operand" "=r")
! (match_operand:SI 2 "s_operand" "oQ"))])]
""
"*
{
--- 1407,1413 ----
(define_insn "*load_multiple_si"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:SI 1 "register_operand" "=r")
! (match_operand:SI 2 "s_operand" "Q"))])]
""
"*
{
***************
*** 1491,1497 ****
(define_insn "*store_multiple_di"
[(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:DI 1 "s_operand" "=oQ")
(match_operand:DI 2 "register_operand" "r"))])]
""
"*
--- 1491,1497 ----
(define_insn "*store_multiple_di"
[(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:DI 1 "s_operand" "=Q")
(match_operand:DI 2 "register_operand" "r"))])]
""
"*
***************
*** 1511,1517 ****
(define_insn "*store_multiple_si"
[(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:SI 1 "s_operand" "=oQ")
(match_operand:SI 2 "register_operand" "r"))])]
""
"*
--- 1511,1517 ----
(define_insn "*store_multiple_si"
[(match_parallel 0 "store_multiple_operation"
! [(set (match_operand:SI 1 "s_operand" "=Q")
(match_operand:SI 2 "register_operand" "r"))])]
""
"*
***************
*** 1697,1704 ****
; The block length is taken as (operands[2] % 256) + 1.
(define_insn "movstrdi_short"
! [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
! (match_operand:BLK 1 "s_operand" "oQ,oQ"))
(use (match_operand:DI 2 "nonmemory_operand" "n,a"))
(clobber (match_scratch:DI 3 "=X,&a"))]
"TARGET_64BIT"
--- 1697,1704 ----
; The block length is taken as (operands[2] % 256) + 1.
(define_insn "movstrdi_short"
! [(set (match_operand:BLK 0 "s_operand" "=Q,Q")
! (match_operand:BLK 1 "s_operand" "Q,Q"))
(use (match_operand:DI 2 "nonmemory_operand" "n,a"))
(clobber (match_scratch:DI 3 "=X,&a"))]
"TARGET_64BIT"
***************
*** 1723,1730 ****
(set_attr "length" "*,14")])
(define_insn "movstrsi_short"
! [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
! (match_operand:BLK 1 "s_operand" "oQ,oQ"))
(use (match_operand:SI 2 "nonmemory_operand" "n,a"))
(clobber (match_scratch:SI 3 "=X,&a"))]
"!TARGET_64BIT"
--- 1723,1730 ----
(set_attr "length" "*,14")])
(define_insn "movstrsi_short"
! [(set (match_operand:BLK 0 "s_operand" "=Q,Q")
! (match_operand:BLK 1 "s_operand" "Q,Q"))
(use (match_operand:SI 2 "nonmemory_operand" "n,a"))
(clobber (match_scratch:SI 3 "=X,&a"))]
"!TARGET_64BIT"
***************
*** 1927,1933 ****
; Clear memory with length less than 256 bytes
(define_insn "clrstrsico"
! [(set (match_operand:BLK 0 "s_operand" "=Qo")
(const_int 0))
(use (match_operand 1 "immediate_operand" "I"))
(clobber (reg:CC 33))]
--- 1927,1933 ----
; Clear memory with length less than 256 bytes
(define_insn "clrstrsico"
! [(set (match_operand:BLK 0 "s_operand" "=Q")
(const_int 0))
(use (match_operand 1 "immediate_operand" "I"))
(clobber (reg:CC 33))]
***************
*** 2111,2118 ****
(define_insn "cmpstr_const"
[(set (reg:CCS 33)
! (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
! (match_operand:BLK 1 "s_operand" "oQ")))
(use (match_operand 2 "immediate_operand" "I"))]
"(unsigned) INTVAL (operands[2]) < 256"
"clc\\t%O0(%c2,%R0),%1"
--- 2111,2118 ----
(define_insn "cmpstr_const"
[(set (reg:CCS 33)
! (compare:CCS (match_operand:BLK 0 "s_operand" "Q")
! (match_operand:BLK 1 "s_operand" "Q")))
(use (match_operand 2 "immediate_operand" "I"))]
"(unsigned) INTVAL (operands[2]) < 256"
"clc\\t%O0(%c2,%R0),%1"
***************
*** 2193,2199 ****
(define_insn "*sethighqisi"
[(set (match_operand:SI 0 "register_operand" "=d")
! (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
(clobber (reg:CC 33))]
""
"icm\\t%0,8,%1"
--- 2193,2199 ----
(define_insn "*sethighqisi"
[(set (match_operand:SI 0 "register_operand" "=d")
! (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
(clobber (reg:CC 33))]
""
"icm\\t%0,8,%1"
***************
*** 2202,2208 ****
(define_insn "*sethighhisi"
[(set (match_operand:SI 0 "register_operand" "=d")
! (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
(clobber (reg:CC 33))]
""
"icm\\t%0,12,%1"
--- 2202,2208 ----
(define_insn "*sethighhisi"
[(set (match_operand:SI 0 "register_operand" "=d")
! (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
(clobber (reg:CC 33))]
""
"icm\\t%0,12,%1"
***************
*** 2211,2217 ****
(define_insn "*sethighqidi_64"
[(set (match_operand:DI 0 "register_operand" "=d")
! (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"icmh\\t%0,8,%1"
--- 2211,2217 ----
(define_insn "*sethighqidi_64"
[(set (match_operand:DI 0 "register_operand" "=d")
! (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"icmh\\t%0,8,%1"
***************
*** 2220,2226 ****
(define_insn "*sethighqidi_31"
[(set (match_operand:DI 0 "register_operand" "=d")
! (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
"icm\\t%0,8,%1"
--- 2220,2226 ----
(define_insn "*sethighqidi_31"
[(set (match_operand:DI 0 "register_operand" "=d")
! (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
"icm\\t%0,8,%1"
***************
*** 4486,4494 ****
(set_attr "atype" "reg,mem")])
(define_insn "*anddi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
(and:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(8,%R0),%1"
--- 4486,4494 ----
(set_attr "atype" "reg,mem")])
(define_insn "*anddi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Q")
(and:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(8,%R0),%1"
***************
*** 4496,4503 ****
(set_attr "atype" "mem")])
(define_insn "*anddi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
! (and:DI (match_operand:DI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4496,4503 ----
(set_attr "atype" "mem")])
(define_insn "*anddi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Q")
! (and:DI (match_operand:DI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4570,4578 ****
(set_attr "atype" "reg,mem")])
(define_insn "*andsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
(and:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(4,%R0),%1"
--- 4570,4578 ----
(set_attr "atype" "reg,mem")])
(define_insn "*andsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Q")
(and:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(4,%R0),%1"
***************
*** 4580,4587 ****
(set_attr "atype" "mem")])
(define_insn "*andsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
! (and:SI (match_operand:SI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4580,4587 ----
(set_attr "atype" "mem")])
(define_insn "*andsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Q")
! (and:SI (match_operand:SI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4616,4624 ****
(set_attr "atype" "reg")])
(define_insn "*andhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
(and:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(2,%R0),%1"
--- 4616,4624 ----
(set_attr "atype" "reg")])
(define_insn "*andhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Q")
(and:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"nc\\t%O0(2,%R0),%1"
***************
*** 4626,4633 ****
(set_attr "atype" "mem")])
(define_insn "*andhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
! (and:HI (match_operand:HI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4626,4633 ----
(set_attr "atype" "mem")])
(define_insn "*andhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Q")
! (and:HI (match_operand:HI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4662,4670 ****
(set_attr "atype" "reg")])
(define_insn "*andqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
(and:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Qo")))
(clobber (reg:CC 33))]
""
"@
--- 4662,4670 ----
(set_attr "atype" "reg")])
(define_insn "*andqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
(and:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Q")))
(clobber (reg:CC 33))]
""
"@
***************
*** 4674,4681 ****
(set_attr "atype" "mem")])
(define_insn "*andqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
! (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4674,4681 ----
(set_attr "atype" "mem")])
(define_insn "*andqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
! (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4757,4765 ****
(set_attr "atype" "reg,mem")])
(define_insn "*iordi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
(ior:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(8,%R0),%1"
--- 4757,4765 ----
(set_attr "atype" "reg,mem")])
(define_insn "*iordi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Q")
(ior:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(8,%R0),%1"
***************
*** 4767,4774 ****
(set_attr "atype" "mem")])
(define_insn "*iordi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
! (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4767,4774 ----
(set_attr "atype" "mem")])
(define_insn "*iordi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Q")
! (ior:DI (match_operand:DI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4841,4849 ****
(set_attr "atype" "reg,mem")])
(define_insn "*iorsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
(ior:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(4,%R0),%1"
--- 4841,4849 ----
(set_attr "atype" "reg,mem")])
(define_insn "*iorsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Q")
(ior:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(4,%R0),%1"
***************
*** 4851,4858 ****
(set_attr "atype" "mem")])
(define_insn "*iorsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
! (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4851,4858 ----
(set_attr "atype" "mem")])
(define_insn "*iorsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Q")
! (ior:SI (match_operand:SI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4887,4895 ****
(set_attr "atype" "reg")])
(define_insn "*iorhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
(ior:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(2,%R0),%1"
--- 4887,4895 ----
(set_attr "atype" "reg")])
(define_insn "*iorhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Q")
(ior:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"oc\\t%O0(2,%R0),%1"
***************
*** 4897,4904 ****
(set_attr "atype" "mem")])
(define_insn "*iorhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
! (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4897,4904 ----
(set_attr "atype" "mem")])
(define_insn "*iorhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Q")
! (ior:HI (match_operand:HI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 4933,4941 ****
(set_attr "atype" "reg")])
(define_insn "*iorqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
(ior:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Qo")))
(clobber (reg:CC 33))]
""
"@
--- 4933,4941 ----
(set_attr "atype" "reg")])
(define_insn "*iorqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
(ior:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Q")))
(clobber (reg:CC 33))]
""
"@
***************
*** 4945,4952 ****
(set_attr "atype" "reg,mem")])
(define_insn "*iorqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
! (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 4945,4952 ----
(set_attr "atype" "reg,mem")])
(define_insn "*iorqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
! (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 5005,5013 ****
(set_attr "atype" "reg,mem")])
(define_insn "*xordi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
(xor:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(8,%R0),%1"
--- 5005,5013 ----
(set_attr "atype" "reg,mem")])
(define_insn "*xordi3_ss"
! [(set (match_operand:DI 0 "s_operand" "=Q")
(xor:DI (match_dup 0)
! (match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(8,%R0),%1"
***************
*** 5015,5022 ****
(set_attr "atype" "mem")])
(define_insn "*xordi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Qo")
! (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 5015,5022 ----
(set_attr "atype" "mem")])
(define_insn "*xordi3_ss_inv"
! [(set (match_operand:DI 0 "s_operand" "=Q")
! (xor:DI (match_operand:DI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 5068,5076 ****
(set_attr "atype" "reg,mem")])
(define_insn "*xorsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
(xor:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(4,%R0),%1"
--- 5068,5076 ----
(set_attr "atype" "reg,mem")])
(define_insn "*xorsi3_ss"
! [(set (match_operand:SI 0 "s_operand" "=Q")
(xor:SI (match_dup 0)
! (match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(4,%R0),%1"
***************
*** 5078,5085 ****
(set_attr "atype" "mem")])
(define_insn "*xorsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Qo")
! (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 5078,5085 ----
(set_attr "atype" "mem")])
(define_insn "*xorsi3_ss_inv"
! [(set (match_operand:SI 0 "s_operand" "=Q")
! (xor:SI (match_operand:SI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 5102,5110 ****
(set_attr "atype" "reg")])
(define_insn "*xorhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
(xor:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Qo")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(2,%R0),%1"
--- 5102,5110 ----
(set_attr "atype" "reg")])
(define_insn "*xorhi3_ss"
! [(set (match_operand:HI 0 "s_operand" "=Q")
(xor:HI (match_dup 0)
! (match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
"xc\\t%O0(2,%R0),%1"
***************
*** 5112,5119 ****
(set_attr "atype" "mem")])
(define_insn "*xorhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Qo")
! (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 5112,5119 ----
(set_attr "atype" "mem")])
(define_insn "*xorhi3_ss_inv"
! [(set (match_operand:HI 0 "s_operand" "=Q")
! (xor:HI (match_operand:HI 1 "s_imm_operand" "Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
***************
*** 5136,5144 ****
(set_attr "atype" "reg")])
(define_insn "*xorqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
(xor:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Qo")))
(clobber (reg:CC 33))]
""
"@
--- 5136,5144 ----
(set_attr "atype" "reg")])
(define_insn "*xorqi3_ss"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
(xor:QI (match_dup 0)
! (match_operand:QI 1 "s_imm_operand" "n,Q")))
(clobber (reg:CC 33))]
""
"@
***************
*** 5148,5155 ****
(set_attr "atype" "mem")])
(define_insn "*xorqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
! (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
(match_dup 0)))
(clobber (reg:CC 33))]
""
--- 5148,5155 ----
(set_attr "atype" "mem")])
(define_insn "*xorqi3_ss_inv"
! [(set (match_operand:QI 0 "s_operand" "=Q,Q")
! (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.155
diff -c -p -r1.155 tm.texi
*** gcc/doc/tm.texi 7 Aug 2002 21:05:12 -0000 1.155
--- gcc/doc/tm.texi 14 Aug 2002 09:46:44 -0000
*************** letter @samp{Q} is defined as representi
*** 2614,2619 ****
--- 2614,2657 ----
a @samp{Q} constraint on the input and @samp{r} on the output. The next
alternative specifies @samp{m} on the input and a register class that
does not include r0 on the output.
+
+ @findex EXTRA_MEMORY_CONSTRAINT
+ @item EXTRA_MEMORY_CONSTRAINT (@var{c})
+ A C expression that defines the optional machine-dependent constraint
+ letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
+ be treated like memory constraints by the reload pass.
+
+ It should return 1 if the operand type represented by the constraint
+ letter @var{c} comprises a subset of all memory references including
+ all those whose address is simply a base register. This allows the reload
+ pass to reload an operand, if it does not directly correspond to the operand
+ type of @var{c}, by copying its address into a base register.
+
+ For example, on the S/390, some instructions do not accept arbitrary
+ memory references, but only those that do not make use of an index
+ register. The constraint letter @samp{Q} is defined via
+ @code{EXTRA_CONSTRAINT} as representing a memory address of this type.
+ If the letter @samp{Q} is marked as @code{EXTRA_MEMORY_CONSTRAINT},
+ a @samp{Q} constraint can handle any memory operand, because the
+ reload pass knows it can be reloaded by copying the memory address
+ into a base register if required. This is analogous to the way
+ a @samp{o} constraint can handle any memory operand.
+
+ @findex EXTRA_ADDRESS_CONSTRAINT
+ @item EXTRA_ADDRESS_CONSTRAINT (@var{c})
+ A C expression that defines the optional machine-dependent constraint
+ letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
+ be treated like address constraints by the reload pass.
+
+ It should return 1 if the operand type represented by the constraint
+ letter @var{c} comprises a subset of all memory addresses including
+ all those that consist of just a base register. This allows the reload
+ pass to reload an operand, if it does not directly correspond to the operand
+ type of @var{c}, by copying it into a base register.
+
+ Any constraint marked as @code{EXTRA_ADDRESS_CONSTRAINT} can only
+ be used with the @code{address_operand} predicate. It is treated
+ analogously to the @samp{p} constraint.
@end table
@node Stack and Calling
Mit freundlichen Gruessen / Best Regards
Ulrich Weigand
--
Dr. Ulrich Weigand
Linux for S/390 Design & Development
IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
Phone: +49-7031/16-3727 --- Email: Ulrich.Weigand@de.ibm.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFC][PATCH] Support multiple variants of memory addresses
2002-08-12 15:32 Ulrich Weigand
@ 2002-08-12 16:30 ` Richard Henderson
0 siblings, 0 replies; 3+ messages in thread
From: Richard Henderson @ 2002-08-12 16:30 UTC (permalink / raw)
To: Ulrich Weigand; +Cc: gcc-patches, uweigand, hpenner
On Tue, Aug 13, 2002 at 12:32:17AM +0200, Ulrich Weigand wrote:
> Do you think this is an acceptable way to solve our problem?
Yes.
> * reload.c (find_reloads): Handle constraint letters marked by
> EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
> (alternative_allows_memconst): Likewise.
> * recog.c (asm_operand_ok, preprocess_constraints,
> constrain_operands): Likewise.
> * regclass.c (record_operand_costs, record_reg_classes): Likewise.
> * local-alloc.c (block_alloc, requires_inout): Likewise.
> * stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
>
> * defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
> (EXTRA_ADDRESS_CONSTRAINT): Likewise.
> * doc/tm.texi: Document these two new target macros.
Looks ok to me.
r~
^ permalink raw reply [flat|nested] 3+ messages in thread
* [RFC][PATCH] Support multiple variants of memory addresses
@ 2002-08-12 15:32 Ulrich Weigand
2002-08-12 16:30 ` Richard Henderson
0 siblings, 1 reply; 3+ messages in thread
From: Ulrich Weigand @ 2002-08-12 15:32 UTC (permalink / raw)
To: gcc-patches; +Cc: uweigand, hpenner
Hello,
this patch introduces a mechanism for the backend to handle
different variants of valid memory addresses.
On the S/390, most instructions accept memory addresses of the
type base + index + displacement, where base and index are two
registers (of class 'a') and displacement is a 12-bit unsigned
immediate value.
Some instructions, however, can only accept addresses of the
type base + displacement, i.e. an index register cannot be
used.
While we currently manage to represent this condition more or
less faithfully using special predicates and constraints, the
result is far from optimal.
To improve the situation, what we'd really like is to make reload
aware of the fact that we have multiple variants of memory
addresses. Now, it is of course possible to define an
EXTRA_CONSTRAINT letter that matches just the subset of memory
addresses that we are interested in. However, if an operand
does not match that constraint, reload does not know how to
handle it.
The solution I'm suggesting is as follows: we add a new target
macro EXTRA_MEMORY_CONSTRAINT that tells reload that particular
constraint letters should be handled 'like memory constraints'.
By returning 1 from this macro, the backend guarantees that
its EXTRA_CONSTRAINT implementation handles these letters in the
following way: on the one hand, every operand accepted by such a
constraint letter must be a memory operand, and on the other
hand every 'trivial' memory operand must be accepted by the
constraint (where a memory operand is trivial if its address is
just a base register).
Given this knowledge, reload (and related passes like regclass)
know that they can treat this constraint like a memory constraint,
and accept any memory operand, because reload will be able to
handle any operand that isn't accepted by the constraint via
copying its address into a base register (this is completely
analogous to the way 'o' constraints are handled).
Likewise, we have a new target macro EXTRA_ADDRESS_CONSTRAINT
that allows to define a variant of the 'p' constraint that
accepts only a subset of all possible memory addresses (again,
this subset must include all 'trivial' addresses, i.e. all
base registers, so that other addresses can be reloaded).
Using this patch (plus a s390 backend patch to actually make
use of the new macros), I was able to bootstrap s390-ibm-linux
successfully. (This patch does not affect in any way targets
that do not define the new macros.)
Do you think this is an acceptable way to solve our problem?
(B.t.w. I haven't considered yet how this patch interacts
with the new register allocator. Any changes to the new
allocator to fully support the new features should probably
be straightforward -- maybe one of the new-regalloc gurus
wants to comment?)
Bye,
Ulrich
ChangeLog:
* reload.c (find_reloads): Handle constraint letters marked by
EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
(alternative_allows_memconst): Likewise.
* recog.c (asm_operand_ok, preprocess_constraints,
constrain_operands): Likewise.
* regclass.c (record_operand_costs, record_reg_classes): Likewise.
* local-alloc.c (block_alloc, requires_inout): Likewise.
* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
* defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
(EXTRA_ADDRESS_CONSTRAINT): Likewise.
* doc/tm.texi: Document these two new target macros.
Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.87
diff -c -p -r1.87 defaults.h
*** gcc/defaults.h 31 Jul 2002 02:10:04 -0000 1.87
--- gcc/defaults.h 12 Aug 2002 22:01:27 -0000
*************** You Lose! You must define PREFERRED_DEB
*** 590,593 ****
--- 590,605 ----
#define DEFAULT_USE_CXA_ATEXIT 0
#endif
+ /* Determine whether extra constraint letter should be handled
+ via address reload (like 'o'). */
+ #ifndef EXTRA_MEMORY_CONSTRAINT
+ #define EXTRA_MEMORY_CONSTRAINT(C) 0
+ #endif
+
+ /* Determine whether extra constraint letter should be handled
+ as an address (like 'p'). */
+ #ifndef EXTRA_ADDRESS_CONSTRAINT
+ #define EXTRA_ADDRESS_CONSTRAINT(C) 0
+ #endif
+
#endif /* ! GCC_DEFAULTS_H */
Index: gcc/local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.109
diff -c -p -r1.109 local-alloc.c
*** gcc/local-alloc.c 30 May 2002 20:55:09 -0000 1.109
--- gcc/local-alloc.c 12 Aug 2002 22:01:29 -0000
*************** block_alloc (b)
*** 1342,1348 ****
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
! if (recog_data.constraints[i][0] == 'p')
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
--- 1342,1349 ----
/* If the operand is an address, find a register in it.
There may be more than one register, but we only try one
of them. */
! if (recog_data.constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0]))
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
*************** requires_inout (p)
*** 2472,2478 ****
break;
default:
! if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
break;
/* FALLTHRU */
case 'p':
--- 2473,2480 ----
break;
default:
! if (REG_CLASS_FROM_LETTER (c) == NO_REGS
! && !EXTRA_ADDRESS_CONSTRAINT (c))
break;
/* FALLTHRU */
case 'p':
Index: gcc/recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.162
diff -c -p -r1.162 recog.c
*** gcc/recog.c 23 Jul 2002 20:50:59 -0000 1.162
--- gcc/recog.c 12 Aug 2002 22:01:32 -0000
*************** asm_operand_ok (op, constraint)
*** 1848,1853 ****
--- 1848,1865 ----
#ifdef EXTRA_CONSTRAINT
if (EXTRA_CONSTRAINT (op, c))
return 1;
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every memory operand can be reloaded to fit. */
+ if (memory_operand (op, VOIDmode))
+ return 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ /* Every address operand can be reloaded to fit. */
+ if (address_operand (op, VOIDmode))
+ return 1;
+ }
#endif
break;
}
*************** preprocess_constraints ()
*** 2287,2292 ****
--- 2299,2317 ----
break;
default:
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ op_alt[j].memory_ok = 1;
+ break;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ op_alt[j].is_address = 1;
+ op_alt[j].class = reg_class_subunion[(int) op_alt[j].class]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ break;
+ }
+
op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)];
break;
}
*************** constrain_operands (strict)
*** 2600,2605 ****
--- 2625,2652 ----
#ifdef EXTRA_CONSTRAINT
else if (EXTRA_CONSTRAINT (op, c))
win = 1;
+
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every memory operand can be reloaded to fit,
+ so copy the condition from the 'm' case. */
+ if (GET_CODE (op) == MEM
+ /* Before reload, accept what reload can turn into mem. */
+ || (strict < 0 && CONSTANT_P (op))
+ /* During reload, accept a pseudo */
+ || (reload_in_progress && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+ win = 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ /* Every address operand can be reloaded to fit,
+ so copy the condition from the 'p' case. */
+ if (strict <= 0
+ || (strict_memory_address_p (recog_data.operand_mode[opno],
+ op)))
+ win = 1;
+ }
#endif
break;
}
Index: gcc/regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.154
diff -c -p -r1.154 regclass.c
*** gcc/regclass.c 23 Jul 2002 20:50:59 -0000 1.154
--- gcc/regclass.c 12 Aug 2002 22:01:34 -0000
*************** record_operand_costs (insn, op_costs, re
*** 1007,1013 ****
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
! else if (constraints[i][0] == 'p')
record_address_regs (recog_data.operand[i],
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
}
--- 1007,1014 ----
if (GET_CODE (recog_data.operand[i]) == MEM)
record_address_regs (XEXP (recog_data.operand[i], 0),
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
! else if (constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
record_address_regs (recog_data.operand[i],
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
}
*************** record_reg_classes (n_alts, n_ops, ops,
*** 1709,1714 ****
--- 1710,1736 ----
#ifdef EXTRA_CONSTRAINT
else if (EXTRA_CONSTRAINT (op, c))
win = 1;
+
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ /* Every MEM can be reloaded to fit. */
+ allows_mem[i] = 1;
+ if (GET_CODE (op) == MEM)
+ win = 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (op))
+ {
+ /* Every address can be reloaded to fit. */
+ allows_addr = 1;
+ if (address_operand (op, GET_MODE (op)))
+ win = 1;
+ /* We know this operand is an address, so we want it to be
+ allocated to a register that can be the base of an
+ address, ie BASE_REG_CLASS. */
+ classes[i]
+ = reg_class_subunion[(int) classes[i]]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ }
#endif
break;
}
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.187
diff -c -p -r1.187 reload.c
*** gcc/reload.c 23 Jul 2002 20:51:00 -0000 1.187
--- gcc/reload.c 12 Aug 2002 22:01:40 -0000
*************** find_reloads (insn, replace, ind_levels,
*** 2641,2647 ****
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
! else if (constraints[i][0] == 'p')
{
find_reloads_address (VOIDmode, (rtx*) 0,
recog_data.operand[i],
--- 2641,2648 ----
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
! else if (constraints[i][0] == 'p'
! || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
{
find_reloads_address (VOIDmode, (rtx*) 0,
recog_data.operand[i],
*************** find_reloads (insn, replace, ind_levels,
*** 3222,3227 ****
--- 3223,3271 ----
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
{
#ifdef EXTRA_CONSTRAINT
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ if (force_reload)
+ break;
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+ /* If the address was already reloaded,
+ we win as well. */
+ if (GET_CODE (operand) == MEM && address_reloaded[i])
+ win = 1;
+ /* Likewise if the address will be reloaded because
+ reg_equiv_address is nonzero. For reg_equiv_mem
+ we have to check. */
+ if (GET_CODE (operand) == REG
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber[REGNO (operand)] < 0
+ && ((reg_equiv_mem[REGNO (operand)] != 0
+ && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
+ || (reg_equiv_address[REGNO (operand)] != 0)))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ constants via force_const_mem, and other
+ MEMs by reloading the address like for 'o'. */
+ if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+ || GET_CODE (operand) == MEM)
+ badop = 0;
+ constmemok = 1;
+ offmemok = 1;
+ break;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ the address into a base register. */
+ this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
+ badop = 0;
+ break;
+ }
+
if (EXTRA_CONSTRAINT (operand, c))
win = 1;
#endif
*************** alternative_allows_memconst (constraint,
*** 4291,4297 ****
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
while ((c = *constraint++) && c != ',' && c != '#')
! if (c == 'm' || c == 'o')
return 1;
return 0;
}
--- 4335,4341 ----
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
while ((c = *constraint++) && c != ',' && c != '#')
! if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
return 1;
return 0;
}
Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.351
diff -c -p -r1.351 reload1.c
*** gcc/reload1.c 30 Jul 2002 16:42:05 -0000 1.351
--- gcc/reload1.c 12 Aug 2002 22:01:46 -0000
*************** maybe_fix_stack_asms ()
*** 1380,1387 ****
break;
default:
! cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
!
}
}
}
--- 1380,1391 ----
break;
default:
! if (EXTRA_ADDRESS_CONSTRAINT (c))
! cls = (int) reg_class_subunion[cls]
! [(int) MODE_BASE_REG_CLASS (VOIDmode)];
! else
! cls = (int) reg_class_subunion[cls]
! [(int) REG_CLASS_FROM_LETTER (c)];
}
}
}
Index: gcc/stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.268
diff -c -p -r1.268 stmt.c
*** gcc/stmt.c 5 Aug 2002 18:46:33 -0000 1.268
--- gcc/stmt.c 12 Aug 2002 22:01:51 -0000
*************** parse_output_constraint (constraint_p, o
*** 1252,1257 ****
--- 1252,1261 ----
if (REG_CLASS_FROM_LETTER (*p) != NO_REGS)
*allows_reg = true;
#ifdef EXTRA_CONSTRAINT
+ else if (EXTRA_ADDRESS_CONSTRAINT (*p))
+ *allows_reg = true;
+ else if (EXTRA_MEMORY_CONSTRAINT (*p))
+ *allows_mem = true;
else
{
/* Otherwise we can't assume anything about the nature of
*************** parse_input_constraint (constraint_p, in
*** 1377,1382 ****
--- 1381,1390 ----
if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
*allows_reg = true;
#ifdef EXTRA_CONSTRAINT
+ else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j]))
+ *allows_reg = true;
+ else if (EXTRA_MEMORY_CONSTRAINT (constraint[j]))
+ *allows_mem = true;
else
{
/* Otherwise we can't assume anything about the nature of
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-08-14 10:15 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-14 3:15 [RFC][PATCH] Support multiple variants of memory addresses Ulrich Weigand
-- strict thread matches above, loose matches on Subject: below --
2002-08-12 15:32 Ulrich Weigand
2002-08-12 16:30 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).