* config/rl78/rl78-real.md (addqi3_real): Allow volatiles.
(addhi3_real): Likewise. Fix [HL+0] syntax.
(subqi3_real): Likewise.
(subhi3_real): Likewise.
(cbranchqi4_real): Likewise. Allow saddr,#imm.
(cbranchhi4_real): Likewise.
(cbranchhi4_real_inverted): Likewise.
(cbranchsi4_real_lt): Likewise.
(cbranchsi4_real_ge): Likewise.
(cbranchsi4_real_ge): Likewise.
* config/rl78/rl78-virt.md (add<mode>3_virt): Likewise.
(sub<mode>3_virt): Likewise.
(cbranchqi4_virt): Likewise.
(cbranchhi4_virt): Likewise.
* config/rl78/rl78.c (rl78_print_operand_1): 'p' modifier means
always use '[reg+imm]' even when imm is zero.
* config/rl78/predicates.md (rl78_volatile_memory_operand): New.
(rl78_general_operand): New.
(rl78_nonimmediate_operand): New.
(rl78_nonfar_operand): Use them.
(rl78_nonfar_nonimm_operand): Likewise.
(rl78_stack_based_mem): Fix.
* config/rl78/constraints.md (Ibqi): New.
(IBqi): New.
(Wsa): New.
(Wsf): New.
(Cs1): Fix.
* config/rl78/rl78-expand.md (andqi3): Accept volatiles.
(iorqi3): Likewise.
(xorqi3): Likewise.
* config/rl78/rl78-protos.h (rl78_sfr_p): New.
* config/rl78/constrains (Qs8): New constraint.
* config/rl78/rl78.c (rl78_flags_already_set): New function.
* config/rl78/rl78-protos.h (rl78_flags_already_set): New prototype.
* config/rl78/rl78-real.md (update_Z): New attribute.
Update patterns to set it.
(cbranchqi4_real): Call rl78_flags_already_set() to determine if a
shorter compare and branch sequence can be used.
(cbranchhi4_real): Likewise.
(cbranchhi4_real_inverted): Likewise.
* config/rl78/predicates.md (uword_operand): Allow symbol_refs.
* config/rl78/rl78-c.c (rl78_register_pragmas): Register __near
address space.
* config/rl78/rl78.c (rl78_get_name_encoding): New.
(rl78_option_override): Allow -mes0 only if C.
(characterize_address): Support subregs of symbol_refs.
(rl78_addr_space_address_mode): Move. Add __near.
(rl78_far_p): Likewise.
(rl78_addr_space_pointer_mode): Likewise.
(rl78_as_legitimate_address): Likewise.
(rl78_addr_space_subset_p): Likewise.
(rl78_addr_space_convert): Likewise.
(rl78_print_operand_1): Support 16-bit addressing of 32-bit
symbols with -mes0.
(transcode_memory_rtx): Don't copy ES if -mes0. Allow symbol[BC]
addressing.
(rl78_alloc_physical_registers_op1): Change logic to prefer
symbol[BC] addressing.
(frodata_section): New.
(rl78_asm_init_sections): Initialize it.
(rl78_select_section): Put __far readonly symbols in .frodata.
(rl78_make_type_far): New.
(rl78_insert_attributes): Force all readonly symbols to be __far when -mes0.
(rl78_asm_out_integer): New.
* config/rl78/rl78.h (ADDR_SPACE_NEAR): New.
* config/rl78/rl78.opt (-mes0): New.
* config/rl78/rl78.h (ASM_OUTPUT_LABELREF): New.
(ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
(ASM_OUTPUT_ALIGNED_DECL_LOCAL): New.
* config/rl78/rl78-protos.h (rl78_output_labelref): New.
(rl78_saddr_p): New.
(rl78_output_aligned_common): New.
* config/rl78/rl78.c (rl78_output_symbol_ref): Strip encodings.
(rl78_handle_saddr_attribute): New.
(rl78_handle_naked_attribute): New.
(rl78_attribute_table): Add saddr.
(rl78_print_operand_1): Don't print '!' on saddr operands.
(rl78_print_operand_1): Strip encodings.
(rl78_sfr_p): New.
(rl78_strip_name_encoding): New.
(rl78_attrlist_to_encoding): New.
(rl78_encode_section_info): New.
(rl78_asm_init_sections): New.
(rl78_select_section): New.
(rl78_output_labelref): New.
(rl78_output_aligned_common): New.
(rl78_asm_out_integer): New.
(rl78_asm_ctor_dtor): New.
(rl78_asm_constructor): New.
(rl78_asm_destructor): New.
* config/rl78/rl78-real.md (movqi_es): Rename to movqi_to_es.
* config/rl78/rl78.c (rl78_expand_epilogue): Update.
(transcode_memory_rtx): Update.
(rl78_expand_epilogue): Use A_REG instead of 0.
Co-Authored-By: Nick Clifton <nickc@redhat.com>
From-SVN: r219791
+2015-01-16 DJ Delorie <dj@redhat.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * config/rl78/rl78-real.md (addqi3_real): Allow volatiles.
+ (addhi3_real): Likewise. Fix [HL+0] syntax.
+ (subqi3_real): Likewise.
+ (subhi3_real): Likewise.
+ (cbranchqi4_real): Likewise. Allow saddr,#imm.
+ (cbranchhi4_real): Likewise.
+ (cbranchhi4_real_inverted): Likewise.
+ (cbranchsi4_real_lt): Likewise.
+ (cbranchsi4_real_ge): Likewise.
+ (cbranchsi4_real_ge): Likewise.
+ * config/rl78/rl78-virt.md (add<mode>3_virt): Likewise.
+ (sub<mode>3_virt): Likewise.
+ (cbranchqi4_virt): Likewise.
+ (cbranchhi4_virt): Likewise.
+ * config/rl78/rl78.c (rl78_print_operand_1): 'p' modifier means
+ always use '[reg+imm]' even when imm is zero.
+ * config/rl78/predicates.md (rl78_volatile_memory_operand): New.
+ (rl78_general_operand): New.
+ (rl78_nonimmediate_operand): New.
+ (rl78_nonfar_operand): Use them.
+ (rl78_nonfar_nonimm_operand): Likewise.
+ (rl78_stack_based_mem): Fix.
+ * config/rl78/constraints.md (Ibqi): New.
+ (IBqi): New.
+ (Wsa): New.
+ (Wsf): New.
+ (Cs1): Fix.
+ * config/rl78/rl78-expand.md (andqi3): Accept volatiles.
+ (iorqi3): Likewise.
+ (xorqi3): Likewise.
+ * config/rl78/rl78-protos.h (rl78_sfr_p): New.
+
+ * config/rl78/constrains (Qs8): New constraint.
+ * config/rl78/rl78.c (rl78_flags_already_set): New function.
+ * config/rl78/rl78-protos.h (rl78_flags_already_set): New prototype.
+ * config/rl78/rl78-real.md (update_Z): New attribute.
+ Update patterns to set it.
+ (cbranchqi4_real): Call rl78_flags_already_set() to determine if a
+ shorter compare and branch sequence can be used.
+ (cbranchhi4_real): Likewise.
+ (cbranchhi4_real_inverted): Likewise.
+
+ * config/rl78/predicates.md (uword_operand): Allow symbol_refs.
+ * config/rl78/rl78-c.c (rl78_register_pragmas): Register __near
+ address space.
+ * config/rl78/rl78.c (rl78_get_name_encoding): New.
+ (rl78_option_override): Allow -mes0 only if C.
+ (characterize_address): Support subregs of symbol_refs.
+ (rl78_addr_space_address_mode): Move. Add __near.
+ (rl78_far_p): Likewise.
+ (rl78_addr_space_pointer_mode): Likewise.
+ (rl78_as_legitimate_address): Likewise.
+ (rl78_addr_space_subset_p): Likewise.
+ (rl78_addr_space_convert): Likewise.
+ (rl78_print_operand_1): Support 16-bit addressing of 32-bit
+ symbols with -mes0.
+ (transcode_memory_rtx): Don't copy ES if -mes0. Allow symbol[BC]
+ addressing.
+ (rl78_alloc_physical_registers_op1): Change logic to prefer
+ symbol[BC] addressing.
+ (frodata_section): New.
+ (rl78_asm_init_sections): Initialize it.
+ (rl78_select_section): Put __far readonly symbols in .frodata.
+ (rl78_make_type_far): New.
+ (rl78_insert_attributes): Force all readonly symbols to be __far when -mes0.
+ (rl78_asm_out_integer): New.
+ * config/rl78/rl78.h (ADDR_SPACE_NEAR): New.
+ * config/rl78/rl78.opt (-mes0): New.
+
+ * config/rl78/rl78.h (ASM_OUTPUT_LABELREF): New.
+ (ASM_OUTPUT_ALIGNED_DECL_COMMON): New.
+ (ASM_OUTPUT_ALIGNED_DECL_LOCAL): New.
+ * config/rl78/rl78-protos.h (rl78_output_labelref): New.
+ (rl78_saddr_p): New.
+ (rl78_output_aligned_common): New.
+ * config/rl78/rl78.c (rl78_output_symbol_ref): Strip encodings.
+ (rl78_handle_saddr_attribute): New.
+ (rl78_handle_naked_attribute): New.
+ (rl78_attribute_table): Add saddr.
+ (rl78_print_operand_1): Don't print '!' on saddr operands.
+ (rl78_print_operand_1): Strip encodings.
+ (rl78_sfr_p): New.
+ (rl78_strip_name_encoding): New.
+ (rl78_attrlist_to_encoding): New.
+ (rl78_encode_section_info): New.
+ (rl78_asm_init_sections): New.
+ (rl78_select_section): New.
+ (rl78_output_labelref): New.
+ (rl78_output_aligned_common): New.
+ (rl78_asm_out_integer): New.
+ (rl78_asm_ctor_dtor): New.
+ (rl78_asm_constructor): New.
+ (rl78_asm_destructor): New.
+
+ * config/rl78/rl78-real.md (movqi_es): Rename to movqi_to_es.
+ * config/rl78/rl78.c (rl78_expand_epilogue): Update.
+ (transcode_memory_rtx): Update.
+ (rl78_expand_epilogue): Use A_REG instead of 0.
+
2015-01-17 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
* config/arm/arm-protos.h (struct tune_params): New field
(and (match_code "const_int")
(match_test "(ival & 0x80) != 0")))
+(define_constraint "Ibqi"
+ "@internal
+ Integer constant with one bit in 0..7 set."
+ (and (match_code "const_int")
+ (match_test "(ival & 0xff) && (exact_log2 (ival & 0xff) >= 0)")))
+(define_constraint "IBqi"
+ "@internal
+ Integer constant with one bit in 0..7 clear."
+ (and (match_code "const_int")
+ (match_test "(~ival & 0xff) && (exact_log2 (~ival & 0xff) >= 0)")))
+
(define_constraint "J"
"Integer constant in the range -255 @dots{} 0"
(and (match_code "const_int")
(and (match_code "plus" "0")
(and (and (match_code "reg" "00")
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))
- (match_test "ubyte_operand (XEXP (XEXP (op, 0), 1), VOIDmode)"))))
+ (and (match_code "const_int" "01")
+ (match_test "IN_RANGE (INTVAL (XEXP (XEXP (op, 0), 1)), 0, 256 - GET_MODE_SIZE (GET_MODE (op)))")))))
)
)
+
(define_memory_constraint "Ws1"
"es:word8[SP]"
(match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op)))
(match_test "rl78_far_p (op)"))
)
+(define_memory_constraint "Wsa"
+ "any SADDR memory access"
+ (and (match_code "mem")
+ (match_test "rl78_saddr_p (op)"))
+)
+
+(define_memory_constraint "Wsf"
+ "any SFR memory access"
+ (and (match_code "mem")
+ (match_test "rl78_sfr_p (op)"))
+)
+
(define_memory_constraint "Y"
"any near legitimate memory access"
(and (match_code "mem")
(define_memory_constraint "Qsc"
"synthetic compares"
(match_code "gt,lt,ge,le"))
+
+(define_constraint "Qs8"
+ "Integer constant computed from (SUBREG (SYMREF))."
+ (and (match_code "subreg")
+ (match_test "GET_CODE (XEXP (op, 0)) == SYMBOL_REF"))
+)
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
\f
-(define_predicate "rl78_any_operand"
+
+(define_predicate "rl78_volatile_memory_operand"
+ (and (match_code "mem")
+ (match_test ("memory_address_addr_space_p (GET_MODE (op), XEXP (op, 0), MEM_ADDR_SPACE (op))")))
+)
+
+; TRUE for any valid general operand. We do this because
+; general_operand refuses to match volatile memory refs.
+
+(define_predicate "rl78_general_operand"
(ior (match_operand 0 "general_operand")
- (match_code "mem,const_int,const_double,reg"))
+ (match_operand 0 "rl78_volatile_memory_operand"))
+)
+
+; Likewise for nonimmediate_operand.
+
+(define_predicate "rl78_nonimmediate_operand"
+ (ior (match_operand 0 "nonimmediate_operand")
+ (match_operand 0 "rl78_volatile_memory_operand"))
)
(define_predicate "rl78_nonfar_operand"
- (and (match_operand 0 "general_operand")
+ (and (match_operand 0 "rl78_general_operand")
(not (match_test "rl78_far_p (op)")))
)
(define_predicate "rl78_nonfar_nonimm_operand"
- (and (match_operand 0 "nonimmediate_operand")
+ (and (match_operand 0 "rl78_nonimmediate_operand")
(not (match_test "rl78_far_p (op)")))
)
(match_test "INTVAL (op) == 2 || INTVAL (op) == 4")))
(define_predicate "uword_operand"
- (ior (match_code "const")
- (and (match_code "const_int")
- (match_test "IN_RANGE (INTVAL (op), 0, 65536)"))))
+ (ior (ior (ior (match_code "const")
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 65536)")))
+ (and (match_code "subreg")
+ (ior (match_code "symbol_ref" "0")
+ (match_code "const" "0"))))
+ (match_code "symbol_ref")
+ ))
(define_predicate "rl78_cmp_operator_signed"
(match_code "gt,ge,lt,le"))
(and (match_code "plus" "0")
(and (match_code "reg" "00")
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")
- (match_code "const_int" "01"))))))
+ (and (match_code "const_int" "01")
+ (match_test "IN_RANGE (INTVAL (XEXP (XEXP (op, 0), 1)), 0, 256 - GET_MODE_SIZE (GET_MODE (op)))"))
+ )))))
void
rl78_register_pragmas (void)
{
+ c_register_addr_space ("__near", ADDR_SPACE_NEAR);
c_register_addr_space ("__far", ADDR_SPACE_FAR);
}
)
(define_expand "andqi3"
- [(set (match_operand:QI 0 "nonimmediate_operand")
- (and:QI (match_operand:QI 1 "general_operand")
- (match_operand:QI 2 "general_operand")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
+ (and:QI (match_operand:QI 1 "rl78_general_operand")
+ (match_operand:QI 2 "rl78_general_operand")))
]
""
"if (rl78_force_nonfar_3 (operands, gen_andqi3))
)
(define_expand "iorqi3"
- [(set (match_operand:QI 0 "nonimmediate_operand")
- (ior:QI (match_operand:QI 1 "general_operand")
- (match_operand:QI 2 "general_operand")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
+ (ior:QI (match_operand:QI 1 "rl78_general_operand")
+ (match_operand:QI 2 "rl78_general_operand")))
]
""
"if (rl78_force_nonfar_3 (operands, gen_iorqi3))
)
(define_expand "xorqi3"
- [(set (match_operand:QI 0 "nonimmediate_operand")
- (xor:QI (match_operand:QI 1 "general_operand")
- (match_operand:QI 2 "general_operand")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
+ (xor:QI (match_operand:QI 1 "rl78_general_operand")
+ (match_operand:QI 2 "rl78_general_operand")))
]
""
"if (rl78_force_nonfar_3 (operands, gen_xorqi3))
bool rl78_es_addr (rtx);
rtx rl78_es_base (rtx);
+
+bool rl78_flags_already_set (rtx, rtx);
+void rl78_output_symbol_ref (FILE *, rtx);
+void rl78_output_labelref (FILE *, const char *);
+int rl78_saddr_p (rtx x);
+int rl78_sfr_p (rtx x);
+void rl78_output_aligned_common (FILE *, tree, const char *,
+ int, int, int);
;; patterns - other than the constraints - so that the operand info is
;; properly set up for the alloc pass.
+;; This attribute reflects how the insn alters the Z flag,
+;; based upon the value of the it's output. The default is NO
+;; for no change, but other possibilities are UPDATE_Z if it changes
+;; the Z flag and CLOBBER if the state of the flag is indeterminate.
+;; The CY and AC flags are not set in the same way as the Z flag, so
+;; their values are not tracked.
+(define_attr "update_Z" "no,update_Z,clobber" (const_string "no"))
+
;;---------- Moving ------------------------
-(define_insn "movqi_es"
+(define_insn "movqi_to_es"
[(set (reg:QI ES_REG)
(match_operand:QI 0 "register_operand" "a"))]
""
)
(define_insn "*movqi_real"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx")
- (match_operand 1 "general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R"))]
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx,WsaWsf")
+ (match_operand 1 "rl78_general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R, i"))]
"rl78_real_insns_ok ()"
"@
; mov\t%0, %1
mov\t%0, %1
mov\t%0, %1
mov\t%0, %1
- mov\t%0, %S1"
+ mov\t%0, %S1
+ mov\t%0, %1"
)
(define_insn "*movhi_real"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
- (match_operand:HI 1 "general_operand" " 0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
+ [(set (match_operand:HI 0 "rl78_nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v")
+ (match_operand:HI 1 "rl78_general_operand" " 0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
"rl78_real_insns_ok ()"
"@
; movw\t%0, %1
;;---------- Arithmetic ------------------------
(define_insn "*addqi3_real"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl")
- (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0")
- (match_operand:QI 2 "general_operand" "K,L,RWhlWh1Wabi,a")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl,Wsa")
+ (plus:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0,0")
+ (match_operand:QI 2 "rl78_general_operand" "K,L,RWhlWh1Wabi,a,i")))
]
"rl78_real_insns_ok ()"
"@
inc\t%0
dec\t%0
add\t%0, %2
+ add\t%0, %2
add\t%0, %2"
+ [(set (attr "update_Z") (const_string "update_Z"))]
)
(define_insn "*addhi3_real"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
- (plus:HI (match_operand:HI 1 "general_operand" "%0,0,0,0,0,0,0,S")
- (match_operand:HI 2 "general_operand" "K,L,N,O,RWh1WhlWabiv,Int8,J,Ri")))
+ [(set (match_operand:HI 0 "rl78_nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A")
+ (plus:HI (match_operand:HI 1 "rl78_general_operand" "%0,0,0,0,0,0,0,S")
+ (match_operand:HI 2 "" "K,L,N,O,RWh1WhlWabiv,Int8Qs8,J,Ri")))
]
"rl78_real_insns_ok ()"
"@
- incw\t%0
- decw\t%0
+ incw\t%p0
+ decw\t%p0
incw\t%0 \;incw\t%0
decw\t%0 \;decw\t%0
addw\t%0, %p2
addw\t%0, %2
subw\t%0, %m2
movw\t%0, %1 \;addw\t%0, %2"
+ [(set_attr "update_Z" "*,*,*,*,update_Z,update_Z,update_Z,update_Z")]
)
(define_insn "*addqihi3a_real"
]
"rl78_real_insns_ok ()"
"add\t%q0, %q1 \;addc\t%Q0, #0"
+ [(set (attr "update_Z") (const_string "update_Z"))]
)
(define_insn "*subqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=a,R,v")
(minus:QI (match_operand:QI 1 "general_operand" "0,0,0")
- (match_operand:QI 2 "general_operand" "RiWabWhbWh1Whl,a,i")))
+ (match_operand:QI 2 "rl78_general_operand" "RiWabWhbWh1Whl,a,i")))
]
"rl78_real_insns_ok ()"
"sub\t%0, %2"
+ [(set (attr "update_Z") (const_string "update_Z"))]
)
(define_insn "*subhi3_real"
[(set (match_operand:HI 0 "nonimmediate_operand" "=A,S")
(minus:HI (match_operand:HI 1 "general_operand" "0,0")
- (match_operand:HI 2 "general_operand" "iBDTWabWh1v,i")))
+ (match_operand:HI 2 "rl78_general_operand" "iBDTWabWh1v,i")))
]
"rl78_real_insns_ok ()"
"subw\t%0, %2"
+ [(set (attr "update_Z") (const_string "update_Z"))]
)
(define_insn "*umulhi3_shift_real"
)
(define_insn "*andqi3_real"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
- (and:QI (match_operand:QI 1 "general_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa")
+ (and:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0")
+ (match_operand:QI 2 "rl78_general_operand" "IBqi,iRvWabWhbWh1Whl,A,i")))
]
"rl78_real_insns_ok ()"
- "and\t%0, %2"
+ "@
+ clr1\t%0.%B2
+ and\t%0, %2
+ and\t%0, %2
+ and\t%0, %2"
+ [(set_attr "update_Z" "*,update_Z,update_Z,update_Z")]
)
(define_insn "*iorqi3_real"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
- (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa")
+ (ior:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0")
+ (match_operand:QI 2 "rl78_general_operand" "Ibqi,iRvWabWhbWh1Whl,A,i")))
]
"rl78_real_insns_ok ()"
- "or\t%0, %2"
+ "@
+ set1\t%0.%B2
+ or\t%0, %2
+ or\t%0, %2
+ or\t%0, %2"
+ [(set_attr "update_Z" "*,update_Z,update_Z,update_Z")]
)
(define_insn "*xorqi3_real"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v")
- (xor:QI (match_operand:QI 1 "general_operand" "%0,0,0")
- (match_operand 2 "general_operand" "iRvWabWhbWh1Whl,A,i")))
+ [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=A,R,vWsa")
+ (xor:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0")
+ (match_operand 2 "rl78_general_operand" "iRvWabWhbWh1Whl,A,i")))
]
"rl78_real_insns_ok ()"
"xor\t%0, %2"
+ [(set (attr "update_Z") (const_string "update_Z"))]
)
;;---------- Shifts ------------------------
shl\t%0, %u2
cmp0 %2\; bz $2f\; 1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
(define_insn "*ashlhi3_real"
shlw\t%0, %u2
cmp0 %2\; bz $2f\; 1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
;;----------
sar\t%0, %u2
cmp0 %2\; bz $2f\; 1: sar\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: sar\t%0, 1\;dec %2 \;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
(define_insn "*ashrhi3_real"
sarw\t%0, %u2
cmp0 %2\; bz $2f\; 1: sarw\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: sarw\t%0, 1\;dec %2\;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
;;----------
shr\t%0, %u2
cmp0 %2\; bz $2f\; 1: shr\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: shr\t%0, 1\;dec %2\;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
(define_insn "*lshrhi3_real"
shrw\t%0, %u2
cmp0 %2\; bz $2f\; 1: shrw\t%0, 1 \;dec %2 \;bnz $1b\;2:
inc %2\;dec %2\;bz $2f\;1: shrw\t%0, 1\;dec %2\;bnz $1b\;2:"
+ [(set_attr "update_Z" "*,clobber,clobber")]
)
;;---------- Branching ------------------------
"@
call\t!!%A0
call\t%A0"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "*call_value_real"
"@
call\t!!%A1
call\t%A1"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "*cbranchqi4_real_signed"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_signed"
- [(match_operand:QI 1 "general_operand" "A,A,A")
- (match_operand:QI 2 "general_operand" "ISqi,i,v")])
+ [(match_operand:QI 1 "general_operand" "A,A,A,A,Wsa")
+ (match_operand:QI 2 "general_operand" "M,ISqi,i,v,i")])
(label_ref (match_operand 3 "" ""))
(pc)))]
"rl78_real_insns_ok ()"
- "@
- cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%C0 \;br\t!!%3
- cmp\t%1, %2 \;xor1 CY,%1.7\;sk%C0 \;br\t!!%3
- cmp\t%1, %2 \;xor1 CY,%1.7\;xor1 CY,%2.7\;sk%C0 \;br\t!!%3"
+ {
+ gcc_assert (GET_CODE (operands[0]) != EQ && GET_CODE (operands[0]) != NE);
+
+ switch (which_alternative)
+ {
+ case 0: return "cmp0\t%1\; xor1\tCY, %1.7\; sk%C0\; br\t!!%3";
+ case 1: return "cmp\t%1, %2\; xor1\tCY, %1.7\; not1\tCY\; sk%C0\; br\t!!%3";
+ case 4:
+ case 2: return "cmp\t%1, %2\; xor1\tCY, %1.7\; sk%C0\; br\t!!%3";
+ case 3: return "cmp\t%1, %2\; xor1\tCY, %1.7\; xor1\tCY, %2.7\; sk%C0\; br\t!!%3";
+ default: gcc_unreachable ();
+ }
+ }
+ [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: flags are set based on %1 vs %2
)
(define_insn "*cbranchqi4_real"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real"
- [(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl")
- (match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")])
+ [(match_operand:QI 1 "rl78_general_operand" "Wabvaxbc,a, vWsaWab,bcdehl")
+ (match_operand:QI 2 "rl78_general_operand" "M, irvWabWhlWh1Whb,i,a")])
(label_ref (match_operand 3 "" ""))
(pc)))]
"rl78_real_insns_ok ()"
- "@
- cmp0\t%1 \;sk%C0 \;br\t!!%3
- cmp\t%1, %2 \;sk%C0 \;br\t!!%3
- cmp\t%1, %2 \;sk%C0 \;br\t!!%3
- cmp\t%1, %2 \;sk%C0 \;br\t!!%3"
+ {
+ if (which_alternative == 0)
+ {
+ if (rl78_flags_already_set (operands[0], operands[1]))
+ return "sk%C0\; br\t!!%3\; # zero-comparison eliminated";
+ else
+ return "cmp0\t%1\; sk%C0\; br\t!!%3";
+ }
+ return "cmp\t%1, %2\; sk%C0\; br\t!!%3";
+ }
+ [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: alt 0: flags are set based on %1 vs %2
)
(define_insn "*cbranchhi4_real_signed"
(pc)))]
"rl78_real_insns_ok ()"
"@
- cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;sk%C0 \;br\t!!%3
- cmpw\t%1, %2 \;xor1 CY,%Q1.7\;sk%C0 \;br\t!!%3
- cmpw\t%1, %2 \;xor1 CY,%Q1.7\;xor1 CY,%Q2.7\;sk%C0 \;br\t!!%3
+ cmpw\t%1, %2\; xor1\tCY, %Q1.7\; not1\tCY\; sk%C0\; br\t!!%3
+ cmpw\t%1, %2\; xor1\tCY, %Q1.7\; sk%C0\; br\t!!%3
+ cmpw\t%1, %2\; xor1\tCY, %Q1.7\; xor1\tCY, %Q2.7\; sk%C0\; br\t!!%3
%z0\t!!%3"
+ [(set_attr "update_Z" "clobber,clobber,clobber,*")]
)
(define_insn "cbranchhi4_real"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real"
- [(match_operand:HI 1 "general_operand" "A,vR")
- (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1,1")])
+ [(match_operand:HI 1 "general_operand" "A,A,vR")
+ (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1,1")])
(label_ref (match_operand 3 "" ""))
(pc)))]
"rl78_real_insns_ok ()"
- "@
- cmpw\t%1, %2 \;sk%C0 \;br\t!!%3
- %z0\t!!%3"
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ if (rl78_flags_already_set (operands[0], operands[1]))
+ return "sk%C0\; br\t!!%3\; # cmpw eliminated";
+ /* else fall through. */
+ case 1:
+ return "cmpw\t%1, %2\; sk%C0\; br\t!!%3";
+ case 2:
+ return "%z0\t!!%3";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: Z might be set based on %1 vs %2
)
(define_insn "cbranchhi4_real_inverted"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real"
- [(match_operand:HI 1 "general_operand" "A")
- (match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1")])
+ [(match_operand:HI 1 "general_operand" "A,A")
+ (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1")])
(pc)
(label_ref (match_operand 3 "" ""))))]
"rl78_real_insns_ok ()"
- "cmpw\t%1, %2 \;sk%C0 \;br\t!!%3"
+ {
+ if (which_alternative == 0 && rl78_flags_already_set (operands[0], operands[1]))
+ return "sk%C0\; br\t!!%3\; # inverted cmpw eliminated";
+ else
+ return "cmpw\t%1, %2\; sk%C0\; br\t!!%3";
+ }
+ [(set (attr "update_Z") (const_string "clobber"))] ;; FIXME: flags are set based on %1 vs %2
)
(define_insn "*cbranchsi4_real_lt"
[(set (pc) (if_then_else
- (lt (match_operand:SI 0 "general_operand" "U,vWabWhlWh1")
+ (lt (match_operand:SI 0 "rl78_general_operand" "U,vWabWhlWh1")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
]
"rl78_real_insns_ok ()"
"@
- mov a, %E0 \;mov1 CY,a.7 \;sknc \;br\t!!%1
- mov1 CY,%E0.7 \;sknc \;br\t!!%1"
+ mov\ta, %E0\; mov1\tCY, a.7\; sknc\; br\t!!%1
+ mov1\tCY, %E0.7\; sknc\; br\t!!%1"
)
(define_insn "*cbranchsi4_real_ge"
[(set (pc) (if_then_else
- (ge (match_operand:SI 0 "general_operand" "U,vWabWhlWh1")
+ (ge (match_operand:SI 0 "rl78_general_operand" "U,vWabWhlWh1")
(const_int 0))
(label_ref (match_operand 1 "" ""))
(pc)))
]
"rl78_real_insns_ok ()"
"@
- mov a, %E0 \;mov1 CY,a.7 \;skc \;br\t!!%1
- mov1 CY,%E0.7 \;skc \;br\t!!%1"
+ mov\ta, %E0\; mov1\tCY, a.7\; skc\; br\t!!%1
+ mov1\tCY, %E0.7\; skc\; br\t!!%1"
)
(define_insn "*cbranchsi4_real_signed"
]
"rl78_real_insns_ok ()"
"@
- movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;not1 CY\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3
- movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\; movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3
- movw ax,%H1 \;cmpw ax, %H2 \;xor1 CY,a.7\;xor1 CY,%E2.7\;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3
- movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a.7\; not1 CY\; movw ax, %h1 \;sknz\; cmpw ax, %h2 \;sk%0 \;br\t!!%3
- movw ax, %H1\; cmpw ax, %H2\; xor1 CY, a.7\; movw ax, %h1\; sknz\; cmpw ax, %h2\; sk%0\; br\t!!%3"
+ movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; not1\tCY\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
+ movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
+ movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; xor1\tCY, %E2.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3
+ movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; not1\tCY\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%0\; br\t!!%3
+ movw\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%0\; br\t!!%3"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "*cbranchsi4_real"
(clobber (reg:HI AX_REG))
]
"rl78_real_insns_ok ()"
- "movw ax,%H1 \;cmpw ax, %H2 \;movw ax,%h1 \;sknz \;cmpw ax, %h2 \;sk%C0 \;br\t!!%3"
+ "movw\tax, %H1\; cmpw\tax, %H2\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%C0\; br\t!!%3"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
;; Peephole to match:
(pc)))]
""
"bf\tA.%B0, $%1"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "bt"
(pc)))]
""
"bt\tA.%B0, $%1"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
;; NOTE: These peepholes are fragile. They rely upon GCC generating
]
"rl78_real_insns_ok ()"
"xor a, #0xff @ xch a, x @ xor a, #0xff @ xch a, x @ addw ax, #1 @ and a, %Q2 @ xch a, x @ and a, %q2 @ xch a, x"
+ [(set (attr "update_Z") (const_string "clobber"))]
)
(define_insn "*add<mode>3_virt"
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vY,S")
(plus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "viY,0")
- (match_operand:QHI 2 "general_operand" "vim,i")))
+ (match_operand:QHI 2 "rl78_general_operand" "vim,i")))
]
"rl78_virt_insns_ok ()"
"v.add\t%0, %1, %2"
(define_insn "*sub<mode>3_virt"
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm,S")
(minus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim,0")
- (match_operand:QHI 2 "general_operand" "vim,i")))
+ (match_operand:QHI 2 "rl78_general_operand" "vim,i")))
]
"rl78_virt_insns_ok ()"
"v.sub\t%0, %1, %2"
(define_insn "*andqi3_virt"
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
(and:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim")
- (match_operand:QI 2 "general_operand" "vim")))
+ (match_operand:QI 2 "rl78_general_operand" "vim")))
]
"rl78_virt_insns_ok ()"
"v.and\t%0, %1, %2"
(define_insn "*iorqi3_virt"
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
(ior:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim")
- (match_operand:QI 2 "general_operand" "vim")))
+ (match_operand:QI 2 "rl78_general_operand" "vim")))
]
"rl78_virt_insns_ok ()"
"v.or\t%0, %1, %2"
)
-(define_insn "*xor3_virt"
+(define_insn "*xorqi3_virt"
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=v,vm,m")
(xor:QI (match_operand:QI 1 "rl78_nonfar_operand" "%0,vm,vm")
- (match_operand 2 "general_operand" "i,vm,vim")))
+ (match_operand 2 "rl78_general_operand" "i,vm,vim")))
]
"rl78_virt_insns_ok ()"
"v.xor\t%0, %1, %2"
(define_insn "*cbranchqi4_virt"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real"
- [(match_operand:QI 1 "general_operand" "vim")
- (match_operand:QI 2 "general_operand" "vim")])
+ [(match_operand:QI 1 "rl78_general_operand" "vim")
+ (match_operand:QI 2 "rl78_general_operand" "vim")])
(label_ref (match_operand 3 "" ""))
(pc)))]
"rl78_virt_insns_ok ()"
(define_insn "*cbranchhi4_virt"
[(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real"
- [(match_operand:HI 1 "general_operand" "vim")
- (match_operand:HI 2 "general_operand" "vim")])
+ [(match_operand:HI 1 "rl78_general_operand" "vim")
+ (match_operand:HI 2 "rl78_general_operand" "vim")])
(label_ref (match_operand 3 "" ""))
(pc)))]
"rl78_virt_insns_ok ()"
#include "tm-constrs.h" /* for satisfies_constraint_*(). */
#include "insn-flags.h" /* for gen_*(). */
#include "builtins.h"
+#include "stringpool.h"
\f
static inline bool is_interrupt_func (const_tree decl);
static inline bool is_brk_interrupt_func (const_tree decl);
static void rl78_reorg (void);
+static const char *rl78_strip_name_encoding (const char *);
+static const char *rl78_strip_nonasm_name_encoding (const char *);
+static section * rl78_select_section (tree, int, unsigned HOST_WIDE_INT);
\f
/* Debugging statements are tagged with DEBUG0 only so that they can
register_pass (& rl78_move_elim_info);
}
+void
+rl78_output_symbol_ref (FILE * file, rtx sym)
+{
+ tree type = SYMBOL_REF_DECL (sym);
+ const char *str = XSTR (sym, 0);
+
+ if (str[0] == '*')
+ {
+ fputs (str + 1, file);
+ }
+ else
+ {
+ str = rl78_strip_nonasm_name_encoding (str);
+ if (type && TREE_CODE (type) == FUNCTION_DECL)
+ {
+ fprintf (file, "%%code(");
+ assemble_name (file, str);
+ fprintf (file, ")");
+ }
+ else
+ assemble_name (file, str);
+ }
+}
\f
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE rl78_option_override
for (i = 24; i < 32; i++)
fixed_regs[i] = 0;
}
+
+ if (TARGET_ES0
+ && strcmp (lang_hooks.name, "GNU C")
+ /* Compiling with -flto results in a language of GNU GIMPLE being used... */
+ && strcmp (lang_hooks.name, "GNU GIMPLE"))
+ /* Address spaces are currently only supported by C. */
+ error ("-mes0 can only be used with C");
}
/* Most registers are 8 bits. Some are 16 bits because, for example,
return NULL_TREE;
}
+/* Check "naked" attributes. */
+static tree
+rl78_handle_naked_attribute (tree * node,
+ tree name ATTRIBUTE_UNUSED,
+ tree args,
+ int flags ATTRIBUTE_UNUSED,
+ bool * no_add_attrs)
+{
+ gcc_assert (DECL_P (* node));
+ gcc_assert (args == NULL_TREE);
+
+ if (TREE_CODE (* node) != FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "naked attribute only applies to functions");
+ * no_add_attrs = true;
+ }
+
+ /* Disable warnings about this function - eg reaching the end without
+ seeing a return statement - because the programmer is doing things
+ that gcc does not know about. */
+ TREE_NO_WARNING (* node) = 1;
+
+ return NULL_TREE;
+}
+
+/* Check "saddr" attributes. */
+static tree
+rl78_handle_saddr_attribute (tree * node,
+ tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool * no_add_attrs)
+{
+ gcc_assert (DECL_P (* node));
+
+ if (TREE_CODE (* node) == FUNCTION_DECL)
+ {
+ warning (OPT_Wattributes, "%qE attribute doesn't apply to functions",
+ name);
+ * no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE rl78_attribute_table
false },
{ "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute,
false },
- { "naked", 0, 0, true, false, false, rl78_handle_func_attribute,
+ { "naked", 0, 0, true, false, false, rl78_handle_naked_attribute,
+ false },
+ { "saddr", 0, 0, true, false, false, rl78_handle_saddr_attribute,
false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
*base = XEXP (x, 0);
x = XEXP (x, 1);
+ if (GET_CODE (*base) == SUBREG)
+ {
+ if (GET_MODE (*base) == HImode
+ && GET_MODE (XEXP (*base, 0)) == SImode
+ && GET_CODE (XEXP (*base, 0)) == REG)
+ {
+ /* This is a throw-away rtx just to tell everyone
+ else what effective register we're using. */
+ *base = gen_rtx_REG (HImode, REGNO (XEXP (*base, 0)));
+ }
+ }
+
if (GET_CODE (*base) != REG
&& GET_CODE (x) == REG)
{
case REG:
return false;
+ case SUBREG:
+ switch (GET_CODE (XEXP (x, 0)))
+ {
+ case CONST:
+ case SYMBOL_REF:
+ case CONST_INT:
+ *addend = x;
+ return true;
+ default:
+ return false;
+ }
+
case CONST:
case SYMBOL_REF:
case CONST_INT:
#define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict)))
+/* Return the appropriate mode for a named address address. */
+
+#undef TARGET_ADDR_SPACE_ADDRESS_MODE
+#define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
+
+static enum machine_mode
+rl78_addr_space_address_mode (addr_space_t addrspace)
+{
+ switch (addrspace)
+ {
+ case ADDR_SPACE_GENERIC:
+ return HImode;
+ case ADDR_SPACE_NEAR:
+ return HImode;
+ case ADDR_SPACE_FAR:
+ return SImode;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Used in various constraints and predicates to match operands in the
"far" address space. */
int
fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
#endif
- return MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR;
+ return GET_MODE_BITSIZE (rl78_addr_space_address_mode (MEM_ADDR_SPACE (x))) == 32;
}
/* Return the appropriate mode for a named address pointer. */
{
case ADDR_SPACE_GENERIC:
return HImode;
+ case ADDR_SPACE_NEAR:
+ return HImode;
case ADDR_SPACE_FAR:
return SImode;
default:
return (m == HImode || m == SImode);
}
-/* Return the appropriate mode for a named address address. */
-#undef TARGET_ADDR_SPACE_ADDRESS_MODE
-#define TARGET_ADDR_SPACE_ADDRESS_MODE rl78_addr_space_address_mode
-
-static machine_mode
-rl78_addr_space_address_mode (addr_space_t addrspace)
-{
- switch (addrspace)
- {
- case ADDR_SPACE_GENERIC:
- return HImode;
- case ADDR_SPACE_FAR:
- return SImode;
- default:
- gcc_unreachable ();
- }
-}
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant
{
rtx base, index, addend;
bool is_far_addr = false;
+ int as_bits;
+
+ as_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (as));
if (GET_CODE (x) == UNSPEC
&& XINT (x, 1) == UNS_ES_ADDR)
is_far_addr = true;
}
- if (as == ADDR_SPACE_GENERIC
- && (GET_MODE (x) == SImode || is_far_addr))
+ if (as_bits == 16 && is_far_addr)
return false;
if (! characterize_address (x, &base, &index, &addend))
involving a register during devirtualization, so make sure all
such __far addresses do not have addends. This forces GCC to do
the sum separately. */
- if (addend && base && as == ADDR_SPACE_FAR)
+ if (addend && base && as_bits == 32 && GET_MODE (base) == SImode)
return false;
if (base && index)
static bool
rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
{
- gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_FAR);
- gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_FAR);
+ int subset_bits;
+ int superset_bits;
- if (subset == superset)
- return true;
+ subset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (subset));
+ superset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (superset));
- else
- return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_FAR);
+ return (subset_bits <= superset_bits);
}
#undef TARGET_ADDR_SPACE_CONVERT
addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
rtx result;
+ int to_bits;
+ int from_bits;
- gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_FAR);
- gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_FAR);
+ to_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (to_as));
+ from_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (from_as));
- if (to_as == ADDR_SPACE_GENERIC && from_as == ADDR_SPACE_FAR)
+ if (to_bits < from_bits)
{
+ rtx tmp;
/* This is unpredictable, as we're truncating off usable address
bits. */
+ warning (OPT_Waddress, "converting far pointer to near pointer");
result = gen_reg_rtx (HImode);
- emit_move_insn (result, simplify_subreg (HImode, op, SImode, 0));
+ if (GET_CODE (op) == SYMBOL_REF
+ || (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+ tmp = gen_rtx_raw_SUBREG (HImode, op, 0);
+ else
+ tmp = simplify_subreg (HImode, op, SImode, 0);
+ gcc_assert (tmp != NULL_RTX);
+ emit_move_insn (result, tmp);
return result;
}
- else if (to_as == ADDR_SPACE_FAR && from_as == ADDR_SPACE_GENERIC)
+ else if (to_bits > from_bits)
{
/* This always works. */
result = gen_reg_rtx (SImode);
emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op);
- emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx);
+ if (TREE_CODE (from_type) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (from_type)) == FUNCTION_TYPE)
+ emit_move_insn (rl78_subreg (HImode, result, SImode, 2), const0_rtx);
+ else
+ emit_move_insn (rl78_subreg (HImode, result, SImode, 2), GEN_INT (0x0f));
return result;
}
else
- gcc_unreachable ();
+ return op;
+ gcc_unreachable ();
}
/* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */
if (TARGET_G10)
{
if (i != 0)
- emit_move_insn (gen_rtx_REG (HImode, 0), gen_rtx_REG (HImode, i * 2));
- F (emit_insn (gen_push (gen_rtx_REG (HImode, 0))));
+ emit_move_insn (gen_rtx_REG (HImode, AX_REG), gen_rtx_REG (HImode, i * 2));
+ F (emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG))));
}
else
{
- int need_bank = i/4;
+ int need_bank = i / 4;
if (need_bank != rb)
{
emit_insn (gen_sel_rb (GEN_INT (need_bank)));
rb = need_bank;
}
- F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2))));
+ F (emit_insn (gen_push (gen_rtx_REG (HImode, i * 2))));
+
}
}
if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
{
emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
- emit_insn (gen_movqi_es (gen_rtx_REG (QImode, A_REG)));
+ emit_insn (gen_movqi_to_es (gen_rtx_REG (QImode, A_REG)));
}
for (i = 15; i >= 0; i--)
if (TARGET_G10)
{
- rtx ax = gen_rtx_REG (HImode, 0);
+ rtx ax = gen_rtx_REG (HImode, AX_REG);
emit_insn (gen_pop (ax));
if (i != 0)
if (rl78_far_p (op))
{
fprintf (file, "es:");
- op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1));
+ if (GET_CODE (XEXP (op, 0)) == UNSPEC)
+ op = gen_rtx_MEM (GET_MODE (op), XVECEXP (XEXP (op, 0), 0, 1));
}
if (letter == 'H')
{
}
if (CONSTANT_P (XEXP (op, 0)))
{
- fprintf (file, "!");
+ if (!rl78_saddr_p (op))
+ fprintf (file, "!");
rl78_print_operand_1 (file, XEXP (op, 0), letter);
}
else if (GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF)
{
- fprintf (file, "!");
+ if (!rl78_saddr_p (op))
+ fprintf (file, "!");
rl78_print_operand_1 (file, XEXP (op, 0), letter);
}
else if (GET_CODE (XEXP (op, 0)) == PLUS
rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u');
fprintf (file, "[");
rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0);
+ if (letter == 'p' && GET_CODE (XEXP (op, 0)) == REG)
+ fprintf (file, "+0");
fprintf (file, "]");
}
else
else if (letter == 'e')
fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
else if (letter == 'B')
- fprintf (file, "%d", exact_log2 (INTVAL (op)));
+ {
+ int ival = INTVAL (op);
+ if (ival == -128)
+ ival = 0x80;
+ if (exact_log2 (ival) >= 0)
+ fprintf (file, "%d", exact_log2 (ival));
+ else
+ fprintf (file, "%d", exact_log2 (~ival & 0xff));
+ }
else if (letter == 'E')
fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff);
else if (letter == 'm')
fprintf (file, ")");
break;
+ case SUBREG:
+ if (GET_MODE (op) == HImode
+ && SUBREG_BYTE (op) == 0)
+ {
+ fprintf (file, "%%lo16(");
+ rl78_print_operand_1 (file, SUBREG_REG (op), 0);
+ fprintf (file, ")");
+ }
+ else if (GET_MODE (op) == HImode
+ && SUBREG_BYTE (op) == 2)
+ {
+ fprintf (file, "%%hi16(");
+ rl78_print_operand_1 (file, SUBREG_REG (op), 0);
+ fprintf (file, ")");
+ }
+ else
+ {
+ fprintf (file, "(%s)", GET_RTX_NAME (GET_CODE (op)));
+ }
+ break;
+
case SYMBOL_REF:
need_paren = 0;
if (letter == 'H')
if (letter == 'q' || letter == 'Q')
output_operand_lossage ("q/Q modifiers invalid for symbol references");
- output_addr_const (file, op);
+ if (SYMBOL_REF_DECL (op) && TREE_CODE (SYMBOL_REF_DECL (op)) == FUNCTION_DECL)
+ {
+ fprintf (file, "%%code(");
+ assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
+ fprintf (file, ")");
+ }
+ else
+ assemble_name (file, rl78_strip_nonasm_name_encoding (XSTR (op, 0)));
if (need_paren)
fprintf (file, ")");
break;
rtx new_m;
rtx seg = rl78_hi8 (XEXP (m, 0));
-#if DEBUG_ALLOC
- fprintf (stderr, "setting ES:\n");
- debug_rtx(seg);
-#endif
- emit_insn_before (EM (gen_movqi (A, seg)), before);
- emit_insn_before (EM (gen_movqi_es (A)), before);
+ if (!TARGET_ES0)
+ {
+ emit_insn_before (EM (gen_movqi (A, seg)), before);
+ emit_insn_before (EM (gen_movqi_to_es (A)), before);
+ }
+
record_content (A, NULL_RTX);
new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
characterize_address (XEXP (m, 0), & base, & index, & addendr);
gcc_assert (index == NULL_RTX);
-#if DEBUG_ALLOC
- fprintf (stderr, "\033[33m"); debug_rtx (m); fprintf (stderr, "\033[0m");
- debug_rtx (base);
-#endif
if (base == NULL_RTX)
return m;
gcc_assert (REG_P (base));
gcc_assert (REG_P (newbase));
+ int limit = 256 - GET_MODE_SIZE (GET_MODE (m));
+
if (REGNO (base) == SP_REG)
{
- if (addend >= 0 && addend <= 255)
+ if (addend >= 0 && addend <= limit)
return m;
}
address. */
if (addend < 0
- || (addend > 255 && REGNO (newbase) != 2)
- || (addendr && GET_CODE (addendr) != CONST_INT))
+ || (addend > limit && REGNO (newbase) != BC_REG)
+ || (addendr
+ && (GET_CODE (addendr) != CONST_INT)
+ && ((REGNO (newbase) != BC_REG))
+ ))
{
/* mov ax, vreg
add ax, #imm
base = newbase;
addend = 0;
+ addendr = 0;
}
else
{
record_content (base, NULL_RTX);
base = gen_rtx_PLUS (HImode, base, GEN_INT (addend));
}
+ else if (addendr)
+ {
+ record_content (base, NULL_RTX);
+ base = gen_rtx_PLUS (HImode, base, addendr);
+ }
-#if DEBUG_ALLOC
- fprintf (stderr, "\033[33m");
- debug_rtx (m);
-#endif
if (need_es)
{
m = change_address (m, GET_MODE (m), gen_es_addr (base));
}
else
m = change_address (m, GET_MODE (m), base);
-#if DEBUG_ALLOC
- debug_rtx (m);
- fprintf (stderr, "\033[0m");
-#endif
return m;
}
{
/* If necessary, load the operands into BC and HL.
Check to see if we already have OP (0) in HL
- and if so, swap the order. */
+ and if so, swap the order.
+
+ It is tempting to perform this optimization when OP(0) does
+ not hold a MEM, but this leads to bigger code in general.
+ The problem is that if OP(1) holds a MEM then swapping it
+ into BC means a BC-relative load is used and these 3 bytes
+ long vs 1 byte for an HL load. */
if (MEM_P (OP (0))
&& already_contains (HL, XEXP (OP (0), 0)))
{
}
\f
+\f
+
+static GTY(()) section * saddr_section;
+static GTY(()) section * frodata_section;
+
+int
+rl78_saddr_p (rtx x)
+{
+ const char * c;
+
+ if (MEM_P (x))
+ x = XEXP (x, 0);
+ if (GET_CODE (x) == PLUS)
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ return 0;
+
+ c = XSTR (x, 0);
+ if (memcmp (c, "@s.", 3) == 0)
+ return 1;
+
+ return 0;
+}
+
+int
+rl78_sfr_p (rtx x)
+{
+ if (MEM_P (x))
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != CONST_INT)
+ return 0;
+
+ if ((INTVAL (x) & 0xFF00) != 0xFF00)
+ return 0;
+
+ return 1;
+}
+
+#undef TARGET_STRIP_NAME_ENCODING
+#define TARGET_STRIP_NAME_ENCODING rl78_strip_name_encoding
+
+static const char *
+rl78_strip_name_encoding (const char * sym)
+{
+ while (1)
+ {
+ if (*sym == '*')
+ sym++;
+ else if (*sym == '@' && sym[2] == '.')
+ sym += 3;
+ else
+ return sym;
+ }
+}
+
+/* Like rl78_strip_name_encoding, but does not strip leading asterisks. This
+ is important if the stripped name is going to be passed to assemble_name()
+ as that handles asterisk prefixed names in a special manner. */
+
+static const char *
+rl78_strip_nonasm_name_encoding (const char * sym)
+{
+ while (1)
+ {
+ if (*sym == '@' && sym[2] == '.')
+ sym += 3;
+ else
+ return sym;
+ }
+}
+
+
+static int
+rl78_attrlist_to_encoding (tree list, tree decl ATTRIBUTE_UNUSED)
+{
+ while (list)
+ {
+ if (is_attribute_p ("saddr", TREE_PURPOSE (list)))
+ return 's';
+ list = TREE_CHAIN (list);
+ }
+
+ return 0;
+}
+
+#define RL78_ATTRIBUTES(decl) \
+ (TYPE_P (decl)) ? TYPE_ATTRIBUTES (decl) \
+ : DECL_ATTRIBUTES (decl) \
+ ? (DECL_ATTRIBUTES (decl)) \
+ : TYPE_ATTRIBUTES (TREE_TYPE (decl))
+
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO rl78_encode_section_info
+
+static void
+rl78_encode_section_info (tree decl, rtx rtl, int first)
+{
+ rtx rtlname;
+ const char * oldname;
+ char encoding;
+ char * newname;
+ tree idp;
+ tree type;
+ tree rl78_attributes;
+
+ if (!first)
+ return;
+
+ rtlname = XEXP (rtl, 0);
+
+ if (GET_CODE (rtlname) == SYMBOL_REF)
+ oldname = XSTR (rtlname, 0);
+ else if (GET_CODE (rtlname) == MEM
+ && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
+ oldname = XSTR (XEXP (rtlname, 0), 0);
+ else
+ gcc_unreachable ();
+
+ type = TREE_TYPE (decl);
+ if (type == error_mark_node)
+ return;
+ if (! DECL_P (decl))
+ return;
+ rl78_attributes = RL78_ATTRIBUTES (decl);
+
+ encoding = rl78_attrlist_to_encoding (rl78_attributes, decl);
+
+ if (encoding)
+ {
+ newname = (char *) alloca (strlen (oldname) + 4);
+ sprintf (newname, "@%c.%s", encoding, oldname);
+ idp = get_identifier (newname);
+ XEXP (rtl, 0) =
+ gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+ SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl);
+ SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl);
+ }
+}
+
+#undef TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS rl78_asm_init_sections
+
+static void
+rl78_asm_init_sections (void)
+{
+ saddr_section
+ = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+ "\t.section .saddr,\"aw\",@progbits");
+ frodata_section
+ = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
+ "\t.section .frodata,\"aw\",@progbits");
+}
+
+#undef TARGET_ASM_SELECT_SECTION
+#define TARGET_ASM_SELECT_SECTION rl78_select_section
+
+static section *
+rl78_select_section (tree decl,
+ int reloc ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+{
+ int readonly = 1;
+
+ switch (TREE_CODE (decl))
+ {
+ case VAR_DECL:
+ if (!TREE_READONLY (decl)
+ || TREE_SIDE_EFFECTS (decl)
+ || !DECL_INITIAL (decl)
+ || (DECL_INITIAL (decl) != error_mark_node
+ && !TREE_CONSTANT (DECL_INITIAL (decl))))
+ readonly = 0;
+ break;
+ case CONSTRUCTOR:
+ if (! TREE_CONSTANT (decl))
+ readonly = 0;
+ break;
+
+ default:
+ break;
+ }
+
+ if (TREE_CODE (decl) == VAR_DECL)
+ {
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+
+ if (name[0] == '@' && name[2] == '.')
+ switch (name[1])
+ {
+ case 's':
+ return saddr_section;
+ }
+
+ if (TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_FAR
+ && readonly)
+ {
+ return frodata_section;
+ }
+ }
+
+ if (readonly)
+ return readonly_data_section;
+
+ return data_section;
+}
+
+void
+rl78_output_labelref (FILE *file, const char *str)
+{
+ const char *str2;
+
+ str2 = targetm.strip_name_encoding (str);
+ if (str2[0] != '.')
+ fputs (user_label_prefix, file);
+ fputs (str2, file);
+}
+
+void
+rl78_output_aligned_common (FILE *stream,
+ tree decl ATTRIBUTE_UNUSED,
+ const char *name,
+ int size, int align, int global)
+{
+ /* We intentionally don't use rl78_section_tag() here. */
+ if (name[0] == '@' && name[2] == '.')
+ {
+ const char *sec = 0;
+ switch (name[1])
+ {
+ case 's':
+ switch_to_section (saddr_section);
+ sec = ".saddr";
+ break;
+ }
+ if (sec)
+ {
+ const char *name2;
+ int p2align = 0;
+
+ while (align > BITS_PER_UNIT)
+ {
+ align /= 2;
+ p2align ++;
+ }
+ name2 = targetm.strip_name_encoding (name);
+ if (global)
+ fprintf (stream, "\t.global\t_%s\n", name2);
+ fprintf (stream, "\t.p2align %d\n", p2align);
+ fprintf (stream, "\t.type\t_%s,@object\n", name2);
+ fprintf (stream, "\t.size\t_%s,%d\n", name2, size);
+ fprintf (stream, "_%s:\n\t.zero\t%d\n", name2, size);
+ return;
+ }
+ }
+
+ if (!global)
+ {
+ fprintf (stream, "\t.local\t");
+ assemble_name (stream, name);
+ fprintf (stream, "\n");
+ }
+ fprintf (stream, "\t.comm\t");
+ assemble_name (stream, name);
+ fprintf (stream, ",%u,%u\n", size, align / BITS_PER_UNIT);
+}
+
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES rl78_insert_attributes
+
+static void
+rl78_insert_attributes (tree decl, tree *attributes ATTRIBUTE_UNUSED)
+{
+ if (TARGET_ES0
+ && TREE_CODE (decl) == VAR_DECL
+ && TREE_READONLY (decl)
+ && TREE_ADDRESSABLE (decl)
+ && TYPE_ADDR_SPACE (TREE_TYPE (decl)) == ADDR_SPACE_GENERIC)
+ {
+ tree type = TREE_TYPE (decl);
+ tree attr = TYPE_ATTRIBUTES (type);
+ int q = TYPE_QUALS_NO_ADDR_SPACE (type) | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_FAR);
+
+ TREE_TYPE (decl) = build_type_attribute_qual_variant (type, attr, q);
+ }
+}
+
+#undef TARGET_ASM_INTEGER
+#define TARGET_ASM_INTEGER rl78_asm_out_integer
+
+static bool
+rl78_asm_out_integer (rtx x, unsigned int size, int aligned_p)
+{
+ if (default_assemble_integer (x, size, aligned_p))
+ return true;
+
+ if (size == 4)
+ {
+ assemble_integer_with_op (".long\t", x);
+ return true;
+ }
+
+ return false;
+}
+
+\f
#undef TARGET_UNWIND_WORD_MODE
#define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode
return HImode;
}
-\f
+#ifndef USE_COLLECT2
+#undef TARGET_ASM_CONSTRUCTOR
+#define TARGET_ASM_CONSTRUCTOR rl78_asm_constructor
+#undef TARGET_ASM_DESTRUCTOR
+#define TARGET_ASM_DESTRUCTOR rl78_asm_destructor
+
+static void
+rl78_asm_ctor_dtor (rtx symbol, int priority, bool is_ctor)
+{
+ section *sec;
+
+ if (priority != DEFAULT_INIT_PRIORITY)
+ {
+ /* This section of the function is based upon code copied
+ from: gcc/varasm.c:get_cdtor_priority_section(). */
+ char buf[16];
+
+ sprintf (buf, "%s.%.5u", is_ctor ? ".ctors" : ".dtors",
+ MAX_INIT_PRIORITY - priority);
+ sec = get_section (buf, 0, NULL);
+ }
+ else
+ sec = is_ctor ? ctors_section : dtors_section;
+
+ assemble_addr_to_section (symbol, sec);
+}
+
+static void
+rl78_asm_constructor (rtx symbol, int priority)
+{
+ rl78_asm_ctor_dtor (symbol, priority, true);
+}
+
+static void
+rl78_asm_destructor (rtx symbol, int priority)
+{
+ rl78_asm_ctor_dtor (symbol, priority, false);
+}
+#endif /* ! USE_COLLECT2 */
+
+/* Scan backwards through the insn chain looking to see if the flags
+ have been set for a comparison of OP against OPERAND. Start with
+ the insn *before* the current insn. */
+
+bool
+rl78_flags_already_set (rtx op, rtx operand)
+{
+ /* We only track the Z flag. */
+ if (GET_CODE (op) != EQ && GET_CODE (op) != NE)
+ return false;
+
+ /* This should not happen, but let's be paranoid. */
+ if (current_output_insn == NULL_RTX)
+ return false;
+
+ rtx_insn *insn;
+ bool res = false;
+
+ for (insn = prev_nonnote_nondebug_insn (current_output_insn);
+ insn != NULL_RTX;
+ insn = prev_nonnote_nondebug_insn (insn))
+ {
+ if (LABEL_P (insn))
+ break;
+
+ if (! INSN_P (insn))
+ continue;
+
+ /* Make sure that the insn can be recognized. */
+ if (recog_memoized (insn) == -1)
+ continue;
+
+ enum attr_update_Z updated = get_attr_update_Z (insn);
+
+ rtx set = single_set (insn);
+ bool must_break = (set != NULL_RTX && rtx_equal_p (operand, SET_DEST (set)));
+
+ switch (updated)
+ {
+ case UPDATE_Z_NO:
+ break;
+ case UPDATE_Z_CLOBBER:
+ must_break = true;
+ break;
+ case UPDATE_Z_UPDATE_Z:
+ res = must_break;
+ must_break = true;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (must_break)
+ break;
+ }
+
+ /* We have to re-recognize the current insn as the call(s) to
+ get_attr_update_Z() above will have overwritten the recog_data cache. */
+ recog_memoized (current_output_insn);
+ cleanup_subreg_operands (current_output_insn);
+ constrain_operands_cached (current_output_insn, 1);
+
+ return res;
+}
+ \f
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rl78.h"
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-#define ADDR_SPACE_FAR 1
+#define ADDR_SPACE_NEAR 1
+#define ADDR_SPACE_FAR 2
#define HAVE_PRE_DECCREMENT 0
#define HAVE_POST_INCREMENT 0
"ALL_REGS" \
}
+/* Note that no class may include the second register in $fp, because
+ we treat $fp as a single HImode register. */
#define REG_CLASS_CONTENTS \
{ \
{ 0x00000000, 0x00000000 }, /* No registers, */ \
fprintf (FILE, "\t.long .L%d - 1b\n", VALUE)
+#define ASM_OUTPUT_SYMBOL_REF(FILE, SYM) rl78_output_symbol_ref ((FILE), (SYM))
+
+#define ASM_OUTPUT_LABELREF(FILE, SYM) rl78_output_labelref ((FILE), (SYM))
+
+#define ASM_OUTPUT_ALIGNED_DECL_COMMON(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
+ rl78_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 1)
+
+#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
+ rl78_output_aligned_common (STREAM, DECL, NAME, SIZE, ALIGNMENT, 0)
+
#define ASM_OUTPUT_ALIGN(STREAM, LOG) \
do \
{ \
mg10
Target Mask(G10) Report
Target the RL78/G10 series
+
+mes0
+Target Mask(ES0)
+Assume ES is zero throughout program execution, use ES: for read-only data.