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:
Ulrich Weigand 2002-08-14 10:04:51 +00:00 committed by Ulrich Weigand
parent 72c41e5adc
commit ccfc6cc8fa
13 changed files with 340 additions and 102 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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. */

View File

@ -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

View File

@ -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))]
""

View File

@ -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 */

View File

@ -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

View File

@ -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':

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)];
}
}
}

View File

@ -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