reload.c (find_reloads): Handle constraint letters marked by EXTRA_ADDRESS_CONSTRAINT and...
* 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'. From-SVN: r56291
This commit is contained in:
parent
72c41e5adc
commit
ccfc6cc8fa
|
@ -1,3 +1,30 @@
|
|||
2002-08-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* 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'.
|
||||
|
||||
2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
|
||||
|
||||
* config/m68hc11/m68hc11.h (LINK_SPEC): Support -mrelax.
|
||||
|
|
|
@ -31,6 +31,7 @@ extern void s390_emit_epilogue PARAMS ((void));
|
|||
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));
|
||||
|
|
|
@ -995,6 +995,28 @@ s_imm_operand (op, mode)
|
|||
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. */
|
||||
|
@ -1386,6 +1408,15 @@ s390_expand_plus_operand (target, src, scratch_in)
|
|||
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
|
||||
it the second one. */
|
||||
|
|
|
@ -533,9 +533,11 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; /* smalled clas
|
|||
/* 'Q' means a memory-reference for a S-type operand. */
|
||||
|
||||
#define EXTRA_CONSTRAINT(OP, C) \
|
||||
((C) == 'Q' ? s_operand (OP, GET_MODE (OP)) : \
|
||||
((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;
|
||||
but on some machines in some cases it is preferable to use a more
|
||||
|
|
|
@ -278,7 +278,7 @@
|
|||
|
||||
(define_insn "*tmqi_ext"
|
||||
[(set (reg 33)
|
||||
(compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
|
||||
(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,7 +345,7 @@
|
|||
|
||||
(define_insn "*tmdi_mem"
|
||||
[(set (reg 33)
|
||||
(compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
|
||||
(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,7 +365,7 @@
|
|||
|
||||
(define_insn "*tmsi_mem"
|
||||
[(set (reg 33)
|
||||
(compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
|
||||
(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,7 +384,7 @@
|
|||
|
||||
(define_insn "*tmhi_mem"
|
||||
[(set (reg 33)
|
||||
(compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
|
||||
(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,7 +403,7 @@
|
|||
|
||||
(define_insn "*tmqi_mem"
|
||||
[(set (reg 33)
|
||||
(compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
|
||||
(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,7 +502,7 @@
|
|||
|
||||
(define_insn "*tsthi"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:HI 0 "s_operand" "Qo")
|
||||
(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,7 +513,7 @@
|
|||
|
||||
(define_insn "*tsthi_cconly"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:HI 0 "s_operand" "Qo")
|
||||
(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,7 +523,7 @@
|
|||
|
||||
(define_insn "*tstqi"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:QI 0 "s_operand" "Qo")
|
||||
(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,7 +534,7 @@
|
|||
|
||||
(define_insn "*tstqi_cconly"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:QI 0 "s_operand" "Qo")
|
||||
(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,7 +628,7 @@
|
|||
(define_insn "*cmphi_ccu"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:HI 0 "register_operand" "d")
|
||||
(match_operand:HI 1 "s_imm_operand" "Qo")))]
|
||||
(match_operand:HI 1 "s_imm_operand" "Q")))]
|
||||
"s390_match_ccmode(insn, CCUmode)"
|
||||
"clm\\t%0,3,%1"
|
||||
[(set_attr "op_type" "RS")
|
||||
|
@ -637,7 +637,7 @@
|
|||
(define_insn "*cmpqi_ccu"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:QI 0 "register_operand" "d")
|
||||
(match_operand:QI 1 "s_imm_operand" "Qo")))]
|
||||
(match_operand:QI 1 "s_imm_operand" "Q")))]
|
||||
"s390_match_ccmode(insn, CCUmode)"
|
||||
"clm\\t%0,1,%1"
|
||||
[(set_attr "op_type" "RS")
|
||||
|
@ -645,7 +645,7 @@
|
|||
|
||||
(define_insn "*cli"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:QI 0 "s_operand" "Qo")
|
||||
(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,8 +654,8 @@
|
|||
|
||||
(define_insn "*cmpdi_ccu_mem"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:DI 0 "s_operand" "oQ")
|
||||
(match_operand:DI 1 "s_imm_operand" "oQ")))]
|
||||
(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,8 +663,8 @@
|
|||
|
||||
(define_insn "*cmpsi_ccu_mem"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:SI 0 "s_operand" "oQ")
|
||||
(match_operand:SI 1 "s_imm_operand" "oQ")))]
|
||||
(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,8 +672,8 @@
|
|||
|
||||
(define_insn "*cmphi_ccu_mem"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:HI 0 "s_operand" "oQ")
|
||||
(match_operand:HI 1 "s_imm_operand" "oQ")))]
|
||||
(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,8 +681,8 @@
|
|||
|
||||
(define_insn "*cmpqi_ccu_mem"
|
||||
[(set (reg 33)
|
||||
(compare (match_operand:QI 0 "s_operand" "oQ")
|
||||
(match_operand:QI 1 "s_imm_operand" "oQ")))]
|
||||
(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,8 +780,8 @@
|
|||
;
|
||||
|
||||
(define_insn "*movti_ss"
|
||||
[(set (match_operand:TI 0 "s_operand" "=Qo")
|
||||
(match_operand:TI 1 "s_imm_operand" "Qo"))]
|
||||
[(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,8 +914,8 @@
|
|||
(set_attr "type" "la")])
|
||||
|
||||
(define_insn "*movdi_ss"
|
||||
[(set (match_operand:DI 0 "s_operand" "=Qo")
|
||||
(match_operand:DI 1 "s_imm_operand" "Qo"))]
|
||||
[(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,8 +1067,8 @@
|
|||
[(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"))]
|
||||
[(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,7 +1156,7 @@
|
|||
|
||||
(define_insn "*movstricthi"
|
||||
[(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
|
||||
(match_operand:HI 1 "s_imm_operand" "Qo"))
|
||||
(match_operand:HI 1 "s_imm_operand" "Q"))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"icm\\t%0,3,%1"
|
||||
|
@ -1197,8 +1197,8 @@
|
|||
}")
|
||||
|
||||
(define_insn "*movdf_ss"
|
||||
[(set (match_operand:DF 0 "s_operand" "=Qo")
|
||||
(match_operand:DF 1 "s_imm_operand" "Qo"))]
|
||||
[(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,8 +1300,8 @@
|
|||
}")
|
||||
|
||||
(define_insn "*movsf_ss"
|
||||
[(set (match_operand:SF 0 "s_operand" "=Qo")
|
||||
(match_operand:SF 1 "s_imm_operand" "Qo"))]
|
||||
[(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,7 +1388,7 @@
|
|||
(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"))])]
|
||||
(match_operand:DI 2 "s_operand" "Q"))])]
|
||||
""
|
||||
"*
|
||||
{
|
||||
|
@ -1407,7 +1407,7 @@
|
|||
(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"))])]
|
||||
(match_operand:SI 2 "s_operand" "Q"))])]
|
||||
""
|
||||
"*
|
||||
{
|
||||
|
@ -1491,7 +1491,7 @@
|
|||
|
||||
(define_insn "*store_multiple_di"
|
||||
[(match_parallel 0 "store_multiple_operation"
|
||||
[(set (match_operand:DI 1 "s_operand" "=oQ")
|
||||
[(set (match_operand:DI 1 "s_operand" "=Q")
|
||||
(match_operand:DI 2 "register_operand" "r"))])]
|
||||
""
|
||||
"*
|
||||
|
@ -1511,7 +1511,7 @@
|
|||
|
||||
(define_insn "*store_multiple_si"
|
||||
[(match_parallel 0 "store_multiple_operation"
|
||||
[(set (match_operand:SI 1 "s_operand" "=oQ")
|
||||
[(set (match_operand:SI 1 "s_operand" "=Q")
|
||||
(match_operand:SI 2 "register_operand" "r"))])]
|
||||
""
|
||||
"*
|
||||
|
@ -1697,8 +1697,8 @@
|
|||
; 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"))
|
||||
[(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,8 +1723,8 @@
|
|||
(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"))
|
||||
[(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,7 +1927,7 @@
|
|||
; Clear memory with length less than 256 bytes
|
||||
|
||||
(define_insn "clrstrsico"
|
||||
[(set (match_operand:BLK 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:BLK 0 "s_operand" "=Q")
|
||||
(const_int 0))
|
||||
(use (match_operand 1 "immediate_operand" "I"))
|
||||
(clobber (reg:CC 33))]
|
||||
|
@ -2111,8 +2111,8 @@
|
|||
|
||||
(define_insn "cmpstr_const"
|
||||
[(set (reg:CCS 33)
|
||||
(compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
|
||||
(match_operand:BLK 1 "s_operand" "oQ")))
|
||||
(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,7 +2193,7 @@
|
|||
|
||||
(define_insn "*sethighqisi"
|
||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||
(unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
|
||||
(unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"icm\\t%0,8,%1"
|
||||
|
@ -2202,7 +2202,7 @@
|
|||
|
||||
(define_insn "*sethighhisi"
|
||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||
(unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
|
||||
(unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"icm\\t%0,12,%1"
|
||||
|
@ -2211,7 +2211,7 @@
|
|||
|
||||
(define_insn "*sethighqidi_64"
|
||||
[(set (match_operand:DI 0 "register_operand" "=d")
|
||||
(unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
|
||||
(unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
|
||||
(clobber (reg:CC 33))]
|
||||
"TARGET_64BIT"
|
||||
"icmh\\t%0,8,%1"
|
||||
|
@ -2220,7 +2220,7 @@
|
|||
|
||||
(define_insn "*sethighqidi_31"
|
||||
[(set (match_operand:DI 0 "register_operand" "=d")
|
||||
(unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
|
||||
(unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
|
||||
(clobber (reg:CC 33))]
|
||||
"!TARGET_64BIT"
|
||||
"icm\\t%0,8,%1"
|
||||
|
@ -4486,9 +4486,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*anddi3_ss"
|
||||
[(set (match_operand:DI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:DI 0 "s_operand" "=Q")
|
||||
(and:DI (match_dup 0)
|
||||
(match_operand:DI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:DI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"nc\\t%O0(8,%R0),%1"
|
||||
|
@ -4496,8 +4496,8 @@
|
|||
(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")
|
||||
[(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,9 +4570,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*andsi3_ss"
|
||||
[(set (match_operand:SI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:SI 0 "s_operand" "=Q")
|
||||
(and:SI (match_dup 0)
|
||||
(match_operand:SI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:SI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"nc\\t%O0(4,%R0),%1"
|
||||
|
@ -4580,8 +4580,8 @@
|
|||
(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")
|
||||
[(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,9 +4616,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*andhi3_ss"
|
||||
[(set (match_operand:HI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:HI 0 "s_operand" "=Q")
|
||||
(and:HI (match_dup 0)
|
||||
(match_operand:HI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:HI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"nc\\t%O0(2,%R0),%1"
|
||||
|
@ -4626,8 +4626,8 @@
|
|||
(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")
|
||||
[(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,9 +4662,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*andqi3_ss"
|
||||
[(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
|
||||
[(set (match_operand:QI 0 "s_operand" "=Q,Q")
|
||||
(and:QI (match_dup 0)
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Qo")))
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"@
|
||||
|
@ -4674,8 +4674,8 @@
|
|||
(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")
|
||||
[(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,9 +4757,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*iordi3_ss"
|
||||
[(set (match_operand:DI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:DI 0 "s_operand" "=Q")
|
||||
(ior:DI (match_dup 0)
|
||||
(match_operand:DI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:DI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"oc\\t%O0(8,%R0),%1"
|
||||
|
@ -4767,8 +4767,8 @@
|
|||
(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")
|
||||
[(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,9 +4841,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*iorsi3_ss"
|
||||
[(set (match_operand:SI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:SI 0 "s_operand" "=Q")
|
||||
(ior:SI (match_dup 0)
|
||||
(match_operand:SI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:SI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"oc\\t%O0(4,%R0),%1"
|
||||
|
@ -4851,8 +4851,8 @@
|
|||
(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")
|
||||
[(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,9 +4887,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*iorhi3_ss"
|
||||
[(set (match_operand:HI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:HI 0 "s_operand" "=Q")
|
||||
(ior:HI (match_dup 0)
|
||||
(match_operand:HI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:HI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"oc\\t%O0(2,%R0),%1"
|
||||
|
@ -4897,8 +4897,8 @@
|
|||
(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")
|
||||
[(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,9 +4933,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*iorqi3_ss"
|
||||
[(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
|
||||
[(set (match_operand:QI 0 "s_operand" "=Q,Q")
|
||||
(ior:QI (match_dup 0)
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Qo")))
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"@
|
||||
|
@ -4945,8 +4945,8 @@
|
|||
(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")
|
||||
[(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,9 +5005,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*xordi3_ss"
|
||||
[(set (match_operand:DI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:DI 0 "s_operand" "=Q")
|
||||
(xor:DI (match_dup 0)
|
||||
(match_operand:DI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:DI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"xc\\t%O0(8,%R0),%1"
|
||||
|
@ -5015,8 +5015,8 @@
|
|||
(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")
|
||||
[(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,9 +5068,9 @@
|
|||
(set_attr "atype" "reg,mem")])
|
||||
|
||||
(define_insn "*xorsi3_ss"
|
||||
[(set (match_operand:SI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:SI 0 "s_operand" "=Q")
|
||||
(xor:SI (match_dup 0)
|
||||
(match_operand:SI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:SI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"xc\\t%O0(4,%R0),%1"
|
||||
|
@ -5078,8 +5078,8 @@
|
|||
(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")
|
||||
[(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,9 +5102,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*xorhi3_ss"
|
||||
[(set (match_operand:HI 0 "s_operand" "=Qo")
|
||||
[(set (match_operand:HI 0 "s_operand" "=Q")
|
||||
(xor:HI (match_dup 0)
|
||||
(match_operand:HI 1 "s_imm_operand" "Qo")))
|
||||
(match_operand:HI 1 "s_imm_operand" "Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"xc\\t%O0(2,%R0),%1"
|
||||
|
@ -5112,8 +5112,8 @@
|
|||
(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")
|
||||
[(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,9 +5136,9 @@
|
|||
(set_attr "atype" "reg")])
|
||||
|
||||
(define_insn "*xorqi3_ss"
|
||||
[(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
|
||||
[(set (match_operand:QI 0 "s_operand" "=Q,Q")
|
||||
(xor:QI (match_dup 0)
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Qo")))
|
||||
(match_operand:QI 1 "s_imm_operand" "n,Q")))
|
||||
(clobber (reg:CC 33))]
|
||||
""
|
||||
"@
|
||||
|
@ -5148,8 +5148,8 @@
|
|||
(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")
|
||||
[(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))]
|
||||
""
|
||||
|
|
|
@ -590,4 +590,16 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
|
|||
#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 */
|
||||
|
|
|
@ -2614,6 +2614,44 @@ letter @samp{Q} is defined as representing a memory address that does
|
|||
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
|
||||
|
|
|
@ -1342,7 +1342,8 @@ block_alloc (b)
|
|||
/* 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')
|
||||
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);
|
||||
|
||||
|
@ -2472,7 +2473,8 @@ requires_inout (p)
|
|||
break;
|
||||
|
||||
default:
|
||||
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
|
||||
if (REG_CLASS_FROM_LETTER (c) == NO_REGS
|
||||
&& !EXTRA_ADDRESS_CONSTRAINT (c))
|
||||
break;
|
||||
/* FALLTHRU */
|
||||
case 'p':
|
||||
|
|
47
gcc/recog.c
47
gcc/recog.c
|
@ -1848,6 +1848,18 @@ asm_operand_ok (op, constraint)
|
|||
#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;
|
||||
}
|
||||
|
@ -2287,6 +2299,19 @@ preprocess_constraints ()
|
|||
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;
|
||||
}
|
||||
|
@ -2600,6 +2625,28 @@ constrain_operands (strict)
|
|||
#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;
|
||||
}
|
||||
|
|
|
@ -1007,7 +1007,8 @@ record_operand_costs (insn, op_costs, reg_pref)
|
|||
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')
|
||||
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);
|
||||
}
|
||||
|
@ -1709,6 +1710,27 @@ record_reg_classes (n_alts, n_ops, ops, modes,
|
|||
#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;
|
||||
}
|
||||
|
|
48
gcc/reload.c
48
gcc/reload.c
|
@ -2641,7 +2641,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
|||
if (*constraints[i] == 0)
|
||||
/* Ignore things like match_operator operands. */
|
||||
;
|
||||
else if (constraints[i][0] == 'p')
|
||||
else if (constraints[i][0] == 'p'
|
||||
|| EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
|
||||
{
|
||||
find_reloads_address (VOIDmode, (rtx*) 0,
|
||||
recog_data.operand[i],
|
||||
|
@ -3222,6 +3223,49 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
|||
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
|
||||
|
@ -4291,7 +4335,7 @@ alternative_allows_memconst (constraint, altnum)
|
|||
/* 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')
|
||||
if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1380,8 +1380,12 @@ maybe_fix_stack_asms ()
|
|||
break;
|
||||
|
||||
default:
|
||||
cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
|
||||
|
||||
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)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1252,6 +1252,10 @@ parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
|
|||
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
|
||||
|
@ -1377,6 +1381,10 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue