Commit 48c528ae by DJ Delorie Committed by DJ Delorie

rl78-real.md (addqi3_real): Allow volatiles.

* 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
parent d31b8797
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> 2015-01-17 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
* config/arm/arm-protos.h (struct tune_params): New field * config/arm/arm-protos.h (struct tune_params): New field
......
...@@ -111,6 +111,17 @@ ...@@ -111,6 +111,17 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "(ival & 0x80) != 0"))) (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" (define_constraint "J"
"Integer constant in the range -255 @dots{} 0" "Integer constant in the range -255 @dots{} 0"
(and (match_code "const_int") (and (match_code "const_int")
...@@ -342,9 +353,11 @@ ...@@ -342,9 +353,11 @@
(and (match_code "plus" "0") (and (match_code "plus" "0")
(and (and (match_code "reg" "00") (and (and (match_code "reg" "00")
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")) (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" (define_memory_constraint "Ws1"
"es:word8[SP]" "es:word8[SP]"
(match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op))) (match_test "(rl78_es_addr (op) && satisfies_constraint_Cs1 (rl78_es_base (op)))
...@@ -357,6 +370,18 @@ ...@@ -357,6 +370,18 @@
(match_test "rl78_far_p (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" (define_memory_constraint "Y"
"any near legitimate memory access" "any near legitimate memory access"
(and (match_code "mem") (and (match_code "mem")
...@@ -384,3 +409,9 @@ ...@@ -384,3 +409,9 @@
(define_memory_constraint "Qsc" (define_memory_constraint "Qsc"
"synthetic compares" "synthetic compares"
(match_code "gt,lt,ge,le")) (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"))
)
...@@ -18,18 +18,34 @@ ...@@ -18,18 +18,34 @@
;; along with GCC; see the file COPYING3. If not see ;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>. ;; <http://www.gnu.org/licenses/>.
(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") (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" (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)"))) (not (match_test "rl78_far_p (op)")))
) )
(define_predicate "rl78_nonfar_nonimm_operand" (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)"))) (not (match_test "rl78_far_p (op)")))
) )
...@@ -47,9 +63,14 @@ ...@@ -47,9 +63,14 @@
(match_test "INTVAL (op) == 2 || INTVAL (op) == 4"))) (match_test "INTVAL (op) == 2 || INTVAL (op) == 4")))
(define_predicate "uword_operand" (define_predicate "uword_operand"
(ior (match_code "const") (ior (ior (ior (match_code "const")
(and (match_code "const_int") (and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 65536)")))) (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" (define_predicate "rl78_cmp_operator_signed"
(match_code "gt,ge,lt,le")) (match_code "gt,ge,lt,le"))
...@@ -73,4 +94,6 @@ ...@@ -73,4 +94,6 @@
(and (match_code "plus" "0") (and (match_code "plus" "0")
(and (match_code "reg" "00") (and (match_code "reg" "00")
(match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG") (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)))"))
)))))
...@@ -39,5 +39,6 @@ ...@@ -39,5 +39,6 @@
void void
rl78_register_pragmas (void) rl78_register_pragmas (void)
{ {
c_register_addr_space ("__near", ADDR_SPACE_NEAR);
c_register_addr_space ("__far", ADDR_SPACE_FAR); c_register_addr_space ("__far", ADDR_SPACE_FAR);
} }
...@@ -150,9 +150,9 @@ ...@@ -150,9 +150,9 @@
) )
(define_expand "andqi3" (define_expand "andqi3"
[(set (match_operand:QI 0 "nonimmediate_operand") [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
(and:QI (match_operand:QI 1 "general_operand") (and:QI (match_operand:QI 1 "rl78_general_operand")
(match_operand:QI 2 "general_operand"))) (match_operand:QI 2 "rl78_general_operand")))
] ]
"" ""
"if (rl78_force_nonfar_3 (operands, gen_andqi3)) "if (rl78_force_nonfar_3 (operands, gen_andqi3))
...@@ -160,9 +160,9 @@ ...@@ -160,9 +160,9 @@
) )
(define_expand "iorqi3" (define_expand "iorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand") [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
(ior:QI (match_operand:QI 1 "general_operand") (ior:QI (match_operand:QI 1 "rl78_general_operand")
(match_operand:QI 2 "general_operand"))) (match_operand:QI 2 "rl78_general_operand")))
] ]
"" ""
"if (rl78_force_nonfar_3 (operands, gen_iorqi3)) "if (rl78_force_nonfar_3 (operands, gen_iorqi3))
...@@ -170,9 +170,9 @@ ...@@ -170,9 +170,9 @@
) )
(define_expand "xorqi3" (define_expand "xorqi3"
[(set (match_operand:QI 0 "nonimmediate_operand") [(set (match_operand:QI 0 "rl78_nonimmediate_operand")
(xor:QI (match_operand:QI 1 "general_operand") (xor:QI (match_operand:QI 1 "rl78_general_operand")
(match_operand:QI 2 "general_operand"))) (match_operand:QI 2 "rl78_general_operand")))
] ]
"" ""
"if (rl78_force_nonfar_3 (operands, gen_xorqi3)) "if (rl78_force_nonfar_3 (operands, gen_xorqi3))
......
...@@ -45,3 +45,11 @@ bool rl78_virt_insns_ok (void); ...@@ -45,3 +45,11 @@ bool rl78_virt_insns_ok (void);
bool rl78_es_addr (rtx); bool rl78_es_addr (rtx);
rtx rl78_es_base (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);
...@@ -27,9 +27,17 @@ ...@@ -27,9 +27,17 @@
;; patterns - other than the constraints - so that the operand info is ;; patterns - other than the constraints - so that the operand info is
;; properly set up for the alloc pass. ;; 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 ------------------------ ;;---------- Moving ------------------------
(define_insn "movqi_es" (define_insn "movqi_to_es"
[(set (reg:QI ES_REG) [(set (reg:QI ES_REG)
(match_operand:QI 0 "register_operand" "a"))] (match_operand:QI 0 "register_operand" "a"))]
"" ""
...@@ -51,8 +59,8 @@ ...@@ -51,8 +59,8 @@
) )
(define_insn "*movqi_real" (define_insn "*movqi_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx") [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=g,RaxbcWab,RaxbcWab,a, bcx,R, WabWd2WhlWh1WhbWbcWs1v, bcx,WsaWsf")
(match_operand 1 "general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R"))] (match_operand 1 "rl78_general_operand" "0,K, M, RInt8sJvWabWdeWd2WhlWh1WhbWbcWs1,Wab,aInt8J,a, R, i"))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
; mov\t%0, %1 ; mov\t%0, %1
...@@ -62,12 +70,13 @@ ...@@ -62,12 +70,13 @@
mov\t%0, %1 mov\t%0, %1
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" (define_insn "*movhi_real"
[(set (match_operand:HI 0 "nonimmediate_operand" "=g,AB,AB,RSv,A,BDTvSWabWd2WdeWhlWh1WbcWs1, BDT,ABDT,v") [(set (match_operand:HI 0 "rl78_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"))] (match_operand:HI 1 "rl78_general_operand" " 0,K, M, i, BDTvSWabWd2WdeWh1WhlWbcWs1,A, BDT,vS, ABDT"))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
; movw\t%0, %1 ; movw\t%0, %1
...@@ -104,33 +113,36 @@ ...@@ -104,33 +113,36 @@
;;---------- Arithmetic ------------------------ ;;---------- Arithmetic ------------------------
(define_insn "*addqi3_real" (define_insn "*addqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl") [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=rvWabWhlWh1,rvWabWhlWh1,a,*bcdehl,Wsa")
(plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") (plus:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0,0")
(match_operand:QI 2 "general_operand" "K,L,RWhlWh1Wabi,a"))) (match_operand:QI 2 "rl78_general_operand" "K,L,RWhlWh1Wabi,a,i")))
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
inc\t%0 inc\t%0
dec\t%0 dec\t%0
add\t%0, %2 add\t%0, %2
add\t%0, %2
add\t%0, %2" add\t%0, %2"
[(set (attr "update_Z") (const_string "update_Z"))]
) )
(define_insn "*addhi3_real" (define_insn "*addhi3_real"
[(set (match_operand:HI 0 "nonimmediate_operand" "=vABDTWh1Wab,vABDTWh1Wab,v,v,A,S,S,A") [(set (match_operand:HI 0 "rl78_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") (plus:HI (match_operand:HI 1 "rl78_general_operand" "%0,0,0,0,0,0,0,S")
(match_operand:HI 2 "general_operand" "K,L,N,O,RWh1WhlWabiv,Int8,J,Ri"))) (match_operand:HI 2 "" "K,L,N,O,RWh1WhlWabiv,Int8Qs8,J,Ri")))
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
incw\t%0 incw\t%p0
decw\t%0 decw\t%p0
incw\t%0 \;incw\t%0 incw\t%0 \;incw\t%0
decw\t%0 \;decw\t%0 decw\t%0 \;decw\t%0
addw\t%0, %p2 addw\t%0, %p2
addw\t%0, %2 addw\t%0, %2
subw\t%0, %m2 subw\t%0, %m2
movw\t%0, %1 \;addw\t%0, %2" movw\t%0, %1 \;addw\t%0, %2"
[(set_attr "update_Z" "*,*,*,*,update_Z,update_Z,update_Z,update_Z")]
) )
(define_insn "*addqihi3a_real" (define_insn "*addqihi3a_real"
...@@ -140,24 +152,27 @@ ...@@ -140,24 +152,27 @@
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"add\t%q0, %q1 \;addc\t%Q0, #0" "add\t%q0, %q1 \;addc\t%Q0, #0"
[(set (attr "update_Z") (const_string "update_Z"))]
) )
(define_insn "*subqi3_real" (define_insn "*subqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=a,R,v") [(set (match_operand:QI 0 "nonimmediate_operand" "=a,R,v")
(minus:QI (match_operand:QI 1 "general_operand" "0,0,0") (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 ()" "rl78_real_insns_ok ()"
"sub\t%0, %2" "sub\t%0, %2"
[(set (attr "update_Z") (const_string "update_Z"))]
) )
(define_insn "*subhi3_real" (define_insn "*subhi3_real"
[(set (match_operand:HI 0 "nonimmediate_operand" "=A,S") [(set (match_operand:HI 0 "nonimmediate_operand" "=A,S")
(minus:HI (match_operand:HI 1 "general_operand" "0,0") (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 ()" "rl78_real_insns_ok ()"
"subw\t%0, %2" "subw\t%0, %2"
[(set (attr "update_Z") (const_string "update_Z"))]
) )
(define_insn "*umulhi3_shift_real" (define_insn "*umulhi3_shift_real"
...@@ -179,30 +194,41 @@ ...@@ -179,30 +194,41 @@
) )
(define_insn "*andqi3_real" (define_insn "*andqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v") [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa")
(and:QI (match_operand:QI 1 "general_operand" "%0,0,0") (and:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0")
(match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i"))) (match_operand:QI 2 "rl78_general_operand" "IBqi,iRvWabWhbWh1Whl,A,i")))
] ]
"rl78_real_insns_ok ()" "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" (define_insn "*iorqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v") [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=Wsf,A,R,vWsa")
(ior:QI (match_operand:QI 1 "general_operand" "%0,0,0") (ior:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0,0")
(match_operand:QI 2 "general_operand" "iRvWabWhbWh1Whl,A,i"))) (match_operand:QI 2 "rl78_general_operand" "Ibqi,iRvWabWhbWh1Whl,A,i")))
] ]
"rl78_real_insns_ok ()" "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" (define_insn "*xorqi3_real"
[(set (match_operand:QI 0 "nonimmediate_operand" "=A,R,v") [(set (match_operand:QI 0 "rl78_nonimmediate_operand" "=A,R,vWsa")
(xor:QI (match_operand:QI 1 "general_operand" "%0,0,0") (xor:QI (match_operand:QI 1 "rl78_general_operand" "%0,0,0")
(match_operand 2 "general_operand" "iRvWabWhbWh1Whl,A,i"))) (match_operand 2 "rl78_general_operand" "iRvWabWhbWh1Whl,A,i")))
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"xor\t%0, %2" "xor\t%0, %2"
[(set (attr "update_Z") (const_string "update_Z"))]
) )
;;---------- Shifts ------------------------ ;;---------- Shifts ------------------------
...@@ -217,6 +243,7 @@ ...@@ -217,6 +243,7 @@
shl\t%0, %u2 shl\t%0, %u2
cmp0 %2\; bz $2f\; 1: shl\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" 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" (define_insn "*ashlhi3_real"
...@@ -229,6 +256,7 @@ ...@@ -229,6 +256,7 @@
shlw\t%0, %u2 shlw\t%0, %u2
cmp0 %2\; bz $2f\; 1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" inc %2\;dec %2\;bz $2f\;1: shlw\t%0, 1 \;dec %2 \;bnz $1b\;2:"
[(set_attr "update_Z" "*,clobber,clobber")]
) )
;;---------- ;;----------
...@@ -243,6 +271,7 @@ ...@@ -243,6 +271,7 @@
sar\t%0, %u2 sar\t%0, %u2
cmp0 %2\; bz $2f\; 1: sar\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" 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" (define_insn "*ashrhi3_real"
...@@ -255,6 +284,7 @@ ...@@ -255,6 +284,7 @@
sarw\t%0, %u2 sarw\t%0, %u2
cmp0 %2\; bz $2f\; 1: sarw\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" inc %2\;dec %2\;bz $2f\;1: sarw\t%0, 1\;dec %2\;bnz $1b\;2:"
[(set_attr "update_Z" "*,clobber,clobber")]
) )
;;---------- ;;----------
...@@ -269,6 +299,7 @@ ...@@ -269,6 +299,7 @@
shr\t%0, %u2 shr\t%0, %u2
cmp0 %2\; bz $2f\; 1: shr\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" 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" (define_insn "*lshrhi3_real"
...@@ -281,6 +312,7 @@ ...@@ -281,6 +312,7 @@
shrw\t%0, %u2 shrw\t%0, %u2
cmp0 %2\; bz $2f\; 1: shrw\t%0, 1 \;dec %2 \;bnz $1b\;2: 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:" inc %2\;dec %2\;bz $2f\;1: shrw\t%0, 1\;dec %2\;bnz $1b\;2:"
[(set_attr "update_Z" "*,clobber,clobber")]
) )
;;---------- Branching ------------------------ ;;---------- Branching ------------------------
...@@ -307,6 +339,7 @@ ...@@ -307,6 +339,7 @@
"@ "@
call\t!!%A0 call\t!!%A0
call\t%A0" call\t%A0"
[(set (attr "update_Z") (const_string "clobber"))]
) )
(define_insn "*call_value_real" (define_insn "*call_value_real"
...@@ -317,35 +350,52 @@ ...@@ -317,35 +350,52 @@
"@ "@
call\t!!%A1 call\t!!%A1
call\t%A1" call\t%A1"
[(set (attr "update_Z") (const_string "clobber"))]
) )
(define_insn "*cbranchqi4_real_signed" (define_insn "*cbranchqi4_real_signed"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_signed" (match_operator 0 "rl78_cmp_operator_signed"
[(match_operand:QI 1 "general_operand" "A,A,A") [(match_operand:QI 1 "general_operand" "A,A,A,A,Wsa")
(match_operand:QI 2 "general_operand" "ISqi,i,v")]) (match_operand:QI 2 "general_operand" "M,ISqi,i,v,i")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ {
cmp\t%1, %2 \;xor1 CY,%1.7\;not1 CY\;sk%C0 \;br\t!!%3 gcc_assert (GET_CODE (operands[0]) != EQ && GET_CODE (operands[0]) != NE);
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" 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" (define_insn "*cbranchqi4_real"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real" (match_operator 0 "rl78_cmp_operator_real"
[(match_operand:QI 1 "general_operand" "Wabvaxbc,a, v,bcdehl") [(match_operand:QI 1 "rl78_general_operand" "Wabvaxbc,a, vWsaWab,bcdehl")
(match_operand:QI 2 "general_operand" "M, irvWabWhlWh1Whb,i,a")]) (match_operand:QI 2 "rl78_general_operand" "M, irvWabWhlWh1Whb,i,a")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ {
cmp0\t%1 \;sk%C0 \;br\t!!%3 if (which_alternative == 0)
cmp\t%1, %2 \;sk%C0 \;br\t!!%3 {
cmp\t%1, %2 \;sk%C0 \;br\t!!%3 if (rl78_flags_already_set (operands[0], operands[1]))
cmp\t%1, %2 \;sk%C0 \;br\t!!%3" 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" (define_insn "*cbranchhi4_real_signed"
...@@ -357,39 +407,59 @@ ...@@ -357,39 +407,59 @@
(pc)))] (pc)))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
cmpw\t%1, %2 \;xor1 CY,%Q1.7\;not1 CY\;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 CY,%Q1.7\;sk%C0 \;br\t!!%3 cmpw\t%1, %2\; xor1\tCY, %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\; xor1\tCY, %Q2.7\; sk%C0\; br\t!!%3
%z0\t!!%3" %z0\t!!%3"
[(set_attr "update_Z" "clobber,clobber,clobber,*")]
) )
(define_insn "cbranchhi4_real" (define_insn "cbranchhi4_real"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real" (match_operator 0 "rl78_cmp_operator_real"
[(match_operand:HI 1 "general_operand" "A,vR") [(match_operand:HI 1 "general_operand" "A,A,vR")
(match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1,1")]) (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1,1")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ {
cmpw\t%1, %2 \;sk%C0 \;br\t!!%3 switch (which_alternative)
%z0\t!!%3" {
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" (define_insn "cbranchhi4_real_inverted"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real" (match_operator 0 "rl78_cmp_operator_real"
[(match_operand:HI 1 "general_operand" "A") [(match_operand:HI 1 "general_operand" "A,A")
(match_operand:HI 2 "general_operand" "iBDTvWabWhlWh1")]) (match_operand:HI 2 "rl78_general_operand" "M,iBDTvWabWhlWh1")])
(pc) (pc)
(label_ref (match_operand 3 "" ""))))] (label_ref (match_operand 3 "" ""))))]
"rl78_real_insns_ok ()" "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" (define_insn "*cbranchsi4_real_lt"
[(set (pc) (if_then_else [(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)) (const_int 0))
(label_ref (match_operand 1 "" "")) (label_ref (match_operand 1 "" ""))
(pc))) (pc)))
...@@ -397,13 +467,13 @@ ...@@ -397,13 +467,13 @@
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
mov a, %E0 \;mov1 CY,a.7 \;sknc \;br\t!!%1 mov\ta, %E0\; mov1\tCY, a.7\; sknc\; br\t!!%1
mov1 CY,%E0.7 \;sknc \;br\t!!%1" mov1\tCY, %E0.7\; sknc\; br\t!!%1"
) )
(define_insn "*cbranchsi4_real_ge" (define_insn "*cbranchsi4_real_ge"
[(set (pc) (if_then_else [(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)) (const_int 0))
(label_ref (match_operand 1 "" "")) (label_ref (match_operand 1 "" ""))
(pc))) (pc)))
...@@ -411,8 +481,8 @@ ...@@ -411,8 +481,8 @@
] ]
"rl78_real_insns_ok ()" "rl78_real_insns_ok ()"
"@ "@
mov a, %E0 \;mov1 CY,a.7 \;skc \;br\t!!%1 mov\ta, %E0\; mov1\tCY, a.7\; skc\; br\t!!%1
mov1 CY,%E0.7 \;skc \;br\t!!%1" mov1\tCY, %E0.7\; skc\; br\t!!%1"
) )
(define_insn "*cbranchsi4_real_signed" (define_insn "*cbranchsi4_real_signed"
...@@ -426,11 +496,12 @@ ...@@ -426,11 +496,12 @@
] ]
"rl78_real_insns_ok ()" "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\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; not1\tCY\; movw\tax, %h1\; sknz\; cmpw\tax, %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\tax, %H1\; cmpw\tax, %H2\; xor1\tCY, a.7\; movw\tax, %h1\; sknz\; cmpw\tax, %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\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 ax, %H1\; cmpw ax, %H2\; xor1 CY, a.7\; not1 CY\; 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%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\; movw\tax, %h1\; sknz\; cmpw\tax, %h2\; sk%0\; br\t!!%3"
[(set (attr "update_Z") (const_string "clobber"))]
) )
(define_insn "*cbranchsi4_real" (define_insn "*cbranchsi4_real"
...@@ -443,7 +514,8 @@ ...@@ -443,7 +514,8 @@
(clobber (reg:HI AX_REG)) (clobber (reg:HI AX_REG))
] ]
"rl78_real_insns_ok ()" "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: ;; Peephole to match:
...@@ -480,6 +552,7 @@ ...@@ -480,6 +552,7 @@
(pc)))] (pc)))]
"" ""
"bf\tA.%B0, $%1" "bf\tA.%B0, $%1"
[(set (attr "update_Z") (const_string "clobber"))]
) )
(define_insn "bt" (define_insn "bt"
...@@ -491,6 +564,7 @@ ...@@ -491,6 +564,7 @@
(pc)))] (pc)))]
"" ""
"bt\tA.%B0, $%1" "bt\tA.%B0, $%1"
[(set (attr "update_Z") (const_string "clobber"))]
) )
;; NOTE: These peepholes are fragile. They rely upon GCC generating ;; NOTE: These peepholes are fragile. They rely upon GCC generating
...@@ -565,4 +639,5 @@ ...@@ -565,4 +639,5 @@
] ]
"rl78_real_insns_ok ()" "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" "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"))]
) )
...@@ -88,7 +88,7 @@ ...@@ -88,7 +88,7 @@
(define_insn "*add<mode>3_virt" (define_insn "*add<mode>3_virt"
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vY,S") [(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vY,S")
(plus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "viY,0") (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 ()" "rl78_virt_insns_ok ()"
"v.add\t%0, %1, %2" "v.add\t%0, %1, %2"
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
(define_insn "*sub<mode>3_virt" (define_insn "*sub<mode>3_virt"
[(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm,S") [(set (match_operand:QHI 0 "rl78_nonfar_nonimm_operand" "=vm,S")
(minus:QHI (match_operand:QHI 1 "rl78_nonfar_operand" "vim,0") (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 ()" "rl78_virt_insns_ok ()"
"v.sub\t%0, %1, %2" "v.sub\t%0, %1, %2"
...@@ -124,7 +124,7 @@ ...@@ -124,7 +124,7 @@
(define_insn "*andqi3_virt" (define_insn "*andqi3_virt"
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm") [(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
(and:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim") (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 ()" "rl78_virt_insns_ok ()"
"v.and\t%0, %1, %2" "v.and\t%0, %1, %2"
...@@ -133,16 +133,16 @@ ...@@ -133,16 +133,16 @@
(define_insn "*iorqi3_virt" (define_insn "*iorqi3_virt"
[(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm") [(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=vm")
(ior:QI (match_operand:QI 1 "rl78_nonfar_operand" "vim") (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 ()" "rl78_virt_insns_ok ()"
"v.or\t%0, %1, %2" "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") [(set (match_operand:QI 0 "rl78_nonfar_nonimm_operand" "=v,vm,m")
(xor:QI (match_operand:QI 1 "rl78_nonfar_operand" "%0,vm,vm") (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 ()" "rl78_virt_insns_ok ()"
"v.xor\t%0, %1, %2" "v.xor\t%0, %1, %2"
...@@ -343,8 +343,8 @@ ...@@ -343,8 +343,8 @@
(define_insn "*cbranchqi4_virt" (define_insn "*cbranchqi4_virt"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real" (match_operator 0 "rl78_cmp_operator_real"
[(match_operand:QI 1 "general_operand" "vim") [(match_operand:QI 1 "rl78_general_operand" "vim")
(match_operand:QI 2 "general_operand" "vim")]) (match_operand:QI 2 "rl78_general_operand" "vim")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"rl78_virt_insns_ok ()" "rl78_virt_insns_ok ()"
...@@ -367,8 +367,8 @@ ...@@ -367,8 +367,8 @@
(define_insn "*cbranchhi4_virt" (define_insn "*cbranchhi4_virt"
[(set (pc) (if_then_else [(set (pc) (if_then_else
(match_operator 0 "rl78_cmp_operator_real" (match_operator 0 "rl78_cmp_operator_real"
[(match_operand:HI 1 "general_operand" "vim") [(match_operand:HI 1 "rl78_general_operand" "vim")
(match_operand:HI 2 "general_operand" "vim")]) (match_operand:HI 2 "rl78_general_operand" "vim")])
(label_ref (match_operand 3 "" "")) (label_ref (match_operand 3 "" ""))
(pc)))] (pc)))]
"rl78_virt_insns_ok ()" "rl78_virt_insns_ok ()"
......
...@@ -85,10 +85,14 @@ ...@@ -85,10 +85,14 @@
#include "tm-constrs.h" /* for satisfies_constraint_*(). */ #include "tm-constrs.h" /* for satisfies_constraint_*(). */
#include "insn-flags.h" /* for gen_*(). */ #include "insn-flags.h" /* for gen_*(). */
#include "builtins.h" #include "builtins.h"
#include "stringpool.h"
static inline bool is_interrupt_func (const_tree decl); static inline bool is_interrupt_func (const_tree decl);
static inline bool is_brk_interrupt_func (const_tree decl); static inline bool is_brk_interrupt_func (const_tree decl);
static void rl78_reorg (void); 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);
/* Debugging statements are tagged with DEBUG0 only so that they can /* Debugging statements are tagged with DEBUG0 only so that they can
...@@ -318,6 +322,29 @@ rl78_asm_file_start (void) ...@@ -318,6 +322,29 @@ rl78_asm_file_start (void)
register_pass (& rl78_move_elim_info); 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);
}
}
#undef TARGET_OPTION_OVERRIDE #undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE rl78_option_override #define TARGET_OPTION_OVERRIDE rl78_option_override
...@@ -338,6 +365,13 @@ rl78_option_override (void) ...@@ -338,6 +365,13 @@ rl78_option_override (void)
for (i = 24; i < 32; i++) for (i = 24; i < 32; i++)
fixed_regs[i] = 0; 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, /* Most registers are 8 bits. Some are 16 bits because, for example,
...@@ -695,6 +729,51 @@ rl78_handle_func_attribute (tree * node, ...@@ -695,6 +729,51 @@ rl78_handle_func_attribute (tree * node,
return NULL_TREE; 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 #undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE rl78_attribute_table #define TARGET_ATTRIBUTE_TABLE rl78_attribute_table
...@@ -707,7 +786,9 @@ const struct attribute_spec rl78_attribute_table[] = ...@@ -707,7 +786,9 @@ const struct attribute_spec rl78_attribute_table[] =
false }, false },
{ "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute, { "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute,
false }, 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 }, false },
{ NULL, 0, 0, false, false, false, NULL, false } { NULL, 0, 0, false, false, false, NULL, false }
}; };
...@@ -748,6 +829,18 @@ characterize_address (rtx x, rtx *base, rtx *index, rtx *addend) ...@@ -748,6 +829,18 @@ characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
*base = XEXP (x, 0); *base = XEXP (x, 0);
x = XEXP (x, 1); 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 if (GET_CODE (*base) != REG
&& GET_CODE (x) == REG) && GET_CODE (x) == REG)
{ {
...@@ -781,6 +874,18 @@ characterize_address (rtx x, rtx *base, rtx *index, rtx *addend) ...@@ -781,6 +874,18 @@ characterize_address (rtx x, rtx *base, rtx *index, rtx *addend)
case REG: case REG:
return false; 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 CONST:
case SYMBOL_REF: case SYMBOL_REF:
case CONST_INT: case CONST_INT:
...@@ -828,6 +933,27 @@ rl78_hl_b_c_addr_p (rtx op) ...@@ -828,6 +933,27 @@ rl78_hl_b_c_addr_p (rtx op)
#define REG_IS(r, regno) (((r) == (regno)) || ((r) >= FIRST_PSEUDO_REGISTER && !(strict))) #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 /* Used in various constraints and predicates to match operands in the
"far" address space. */ "far" address space. */
int int
...@@ -839,7 +965,7 @@ rl78_far_p (rtx x) ...@@ -839,7 +965,7 @@ rl78_far_p (rtx x)
fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x); fprintf (stderr, "\033[35mrl78_far_p: "); debug_rtx (x);
fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR); fprintf (stderr, " = %d\033[0m\n", MEM_ADDR_SPACE (x) == ADDR_SPACE_FAR);
#endif #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. */ /* Return the appropriate mode for a named address pointer. */
...@@ -853,6 +979,8 @@ rl78_addr_space_pointer_mode (addr_space_t addrspace) ...@@ -853,6 +979,8 @@ rl78_addr_space_pointer_mode (addr_space_t addrspace)
{ {
case ADDR_SPACE_GENERIC: case ADDR_SPACE_GENERIC:
return HImode; return HImode;
case ADDR_SPACE_NEAR:
return HImode;
case ADDR_SPACE_FAR: case ADDR_SPACE_FAR:
return SImode; return SImode;
default: default:
...@@ -870,23 +998,6 @@ rl78_valid_pointer_mode (machine_mode m) ...@@ -870,23 +998,6 @@ rl78_valid_pointer_mode (machine_mode m)
return (m == HImode || m == SImode); 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 #undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant #define TARGET_LEGITIMATE_CONSTANT_P rl78_is_legitimate_constant
...@@ -906,6 +1017,9 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x, ...@@ -906,6 +1017,9 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
{ {
rtx base, index, addend; rtx base, index, addend;
bool is_far_addr = false; bool is_far_addr = false;
int as_bits;
as_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (as));
if (GET_CODE (x) == UNSPEC if (GET_CODE (x) == UNSPEC
&& XINT (x, 1) == UNS_ES_ADDR) && XINT (x, 1) == UNS_ES_ADDR)
...@@ -914,8 +1028,7 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x, ...@@ -914,8 +1028,7 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
is_far_addr = true; is_far_addr = true;
} }
if (as == ADDR_SPACE_GENERIC if (as_bits == 16 && is_far_addr)
&& (GET_MODE (x) == SImode || is_far_addr))
return false; return false;
if (! characterize_address (x, &base, &index, &addend)) if (! characterize_address (x, &base, &index, &addend))
...@@ -925,7 +1038,7 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x, ...@@ -925,7 +1038,7 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
involving a register during devirtualization, so make sure all involving a register during devirtualization, so make sure all
such __far addresses do not have addends. This forces GCC to do such __far addresses do not have addends. This forces GCC to do
the sum separately. */ the sum separately. */
if (addend && base && as == ADDR_SPACE_FAR) if (addend && base && as_bits == 32 && GET_MODE (base) == SImode)
return false; return false;
if (base && index) if (base && index)
...@@ -956,14 +1069,13 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x, ...@@ -956,14 +1069,13 @@ rl78_as_legitimate_address (machine_mode mode ATTRIBUTE_UNUSED, rtx x,
static bool static bool
rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset) rl78_addr_space_subset_p (addr_space_t subset, addr_space_t superset)
{ {
gcc_assert (subset == ADDR_SPACE_GENERIC || subset == ADDR_SPACE_FAR); int subset_bits;
gcc_assert (superset == ADDR_SPACE_GENERIC || superset == ADDR_SPACE_FAR); int superset_bits;
if (subset == superset) subset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (subset));
return true; superset_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (superset));
else return (subset_bits <= superset_bits);
return (subset == ADDR_SPACE_GENERIC && superset == ADDR_SPACE_FAR);
} }
#undef TARGET_ADDR_SPACE_CONVERT #undef TARGET_ADDR_SPACE_CONVERT
...@@ -976,29 +1088,44 @@ rl78_addr_space_convert (rtx op, tree from_type, tree to_type) ...@@ -976,29 +1088,44 @@ rl78_addr_space_convert (rtx op, tree from_type, tree to_type)
addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type)); addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type));
addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type)); addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type));
rtx result; rtx result;
int to_bits;
int from_bits;
gcc_assert (from_as == ADDR_SPACE_GENERIC || from_as == ADDR_SPACE_FAR); to_bits = GET_MODE_BITSIZE (rl78_addr_space_address_mode (to_as));
gcc_assert (to_as == ADDR_SPACE_GENERIC || to_as == ADDR_SPACE_FAR); 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 /* This is unpredictable, as we're truncating off usable address
bits. */ bits. */
warning (OPT_Waddress, "converting far pointer to near pointer");
result = gen_reg_rtx (HImode); 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; return result;
} }
else if (to_as == ADDR_SPACE_FAR && from_as == ADDR_SPACE_GENERIC) else if (to_bits > from_bits)
{ {
/* This always works. */ /* This always works. */
result = gen_reg_rtx (SImode); result = gen_reg_rtx (SImode);
emit_move_insn (rl78_subreg (HImode, result, SImode, 0), op); 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; return result;
} }
else else
gcc_unreachable (); return op;
gcc_unreachable ();
} }
/* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */ /* Implements REGNO_MODE_CODE_OK_FOR_BASE_P. */
...@@ -1129,19 +1256,20 @@ rl78_expand_prologue (void) ...@@ -1129,19 +1256,20 @@ rl78_expand_prologue (void)
if (TARGET_G10) if (TARGET_G10)
{ {
if (i != 0) if (i != 0)
emit_move_insn (gen_rtx_REG (HImode, 0), gen_rtx_REG (HImode, i * 2)); emit_move_insn (gen_rtx_REG (HImode, AX_REG), gen_rtx_REG (HImode, i * 2));
F (emit_insn (gen_push (gen_rtx_REG (HImode, 0)))); F (emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG))));
} }
else else
{ {
int need_bank = i/4; int need_bank = i / 4;
if (need_bank != rb) if (need_bank != rb)
{ {
emit_insn (gen_sel_rb (GEN_INT (need_bank))); emit_insn (gen_sel_rb (GEN_INT (need_bank)));
rb = 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))));
} }
} }
...@@ -1205,7 +1333,7 @@ rl78_expand_epilogue (void) ...@@ -1205,7 +1333,7 @@ rl78_expand_epilogue (void)
if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es) if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
{ {
emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG))); 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--) for (i = 15; i >= 0; i--)
...@@ -1215,7 +1343,7 @@ rl78_expand_epilogue (void) ...@@ -1215,7 +1343,7 @@ rl78_expand_epilogue (void)
if (TARGET_G10) if (TARGET_G10)
{ {
rtx ax = gen_rtx_REG (HImode, 0); rtx ax = gen_rtx_REG (HImode, AX_REG);
emit_insn (gen_pop (ax)); emit_insn (gen_pop (ax));
if (i != 0) if (i != 0)
...@@ -1415,7 +1543,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1415,7 +1543,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
if (rl78_far_p (op)) if (rl78_far_p (op))
{ {
fprintf (file, "es:"); 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 (letter == 'H')
{ {
...@@ -1449,13 +1578,15 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1449,13 +1578,15 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
} }
if (CONSTANT_P (XEXP (op, 0))) if (CONSTANT_P (XEXP (op, 0)))
{ {
fprintf (file, "!"); if (!rl78_saddr_p (op))
fprintf (file, "!");
rl78_print_operand_1 (file, XEXP (op, 0), letter); rl78_print_operand_1 (file, XEXP (op, 0), letter);
} }
else if (GET_CODE (XEXP (op, 0)) == PLUS else if (GET_CODE (XEXP (op, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == SYMBOL_REF) && 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); rl78_print_operand_1 (file, XEXP (op, 0), letter);
} }
else if (GET_CODE (XEXP (op, 0)) == PLUS else if (GET_CODE (XEXP (op, 0)) == PLUS
...@@ -1465,6 +1596,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1465,6 +1596,8 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u'); rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 1), 'u');
fprintf (file, "["); fprintf (file, "[");
rl78_print_operand_1 (file, XEXP (XEXP (op, 0), 0), 0); 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, "]"); fprintf (file, "]");
} }
else else
...@@ -1513,7 +1646,15 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1513,7 +1646,15 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
else if (letter == 'e') else if (letter == 'e')
fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff); fprintf (file, "%ld", (INTVAL (op) >> 16) & 0xff);
else if (letter == 'B') 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') else if (letter == 'E')
fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff); fprintf (file, "%ld", (INTVAL (op) >> 24) & 0xff);
else if (letter == 'm') else if (letter == 'm')
...@@ -1597,6 +1738,27 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1597,6 +1738,27 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
fprintf (file, ")"); fprintf (file, ")");
break; 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: case SYMBOL_REF:
need_paren = 0; need_paren = 0;
if (letter == 'H') if (letter == 'H')
...@@ -1620,7 +1782,14 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter) ...@@ -1620,7 +1782,14 @@ rl78_print_operand_1 (FILE * file, rtx op, int letter)
if (letter == 'q' || letter == 'Q') if (letter == 'q' || letter == 'Q')
output_operand_lossage ("q/Q modifiers invalid for symbol references"); 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) if (need_paren)
fprintf (file, ")"); fprintf (file, ")");
break; break;
...@@ -2488,12 +2657,12 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2488,12 +2657,12 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
rtx new_m; rtx new_m;
rtx seg = rl78_hi8 (XEXP (m, 0)); rtx seg = rl78_hi8 (XEXP (m, 0));
#if DEBUG_ALLOC if (!TARGET_ES0)
fprintf (stderr, "setting ES:\n"); {
debug_rtx(seg); emit_insn_before (EM (gen_movqi (A, seg)), before);
#endif emit_insn_before (EM (gen_movqi_to_es (A)), before);
emit_insn_before (EM (gen_movqi (A, seg)), before); }
emit_insn_before (EM (gen_movqi_es (A)), before);
record_content (A, NULL_RTX); record_content (A, NULL_RTX);
new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0))); new_m = gen_rtx_MEM (GET_MODE (m), rl78_lo16 (XEXP (m, 0)));
...@@ -2505,10 +2674,6 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2505,10 +2674,6 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
characterize_address (XEXP (m, 0), & base, & index, & addendr); characterize_address (XEXP (m, 0), & base, & index, & addendr);
gcc_assert (index == NULL_RTX); 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) if (base == NULL_RTX)
return m; return m;
...@@ -2518,9 +2683,11 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2518,9 +2683,11 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
gcc_assert (REG_P (base)); gcc_assert (REG_P (base));
gcc_assert (REG_P (newbase)); gcc_assert (REG_P (newbase));
int limit = 256 - GET_MODE_SIZE (GET_MODE (m));
if (REGNO (base) == SP_REG) if (REGNO (base) == SP_REG)
{ {
if (addend >= 0 && addend <= 255) if (addend >= 0 && addend <= limit)
return m; return m;
} }
...@@ -2529,8 +2696,11 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2529,8 +2696,11 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
address. */ address. */
if (addend < 0 if (addend < 0
|| (addend > 255 && REGNO (newbase) != 2) || (addend > limit && REGNO (newbase) != BC_REG)
|| (addendr && GET_CODE (addendr) != CONST_INT)) || (addendr
&& (GET_CODE (addendr) != CONST_INT)
&& ((REGNO (newbase) != BC_REG))
))
{ {
/* mov ax, vreg /* mov ax, vreg
add ax, #imm add ax, #imm
...@@ -2543,6 +2713,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2543,6 +2713,7 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
base = newbase; base = newbase;
addend = 0; addend = 0;
addendr = 0;
} }
else else
{ {
...@@ -2554,11 +2725,12 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2554,11 +2725,12 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
record_content (base, NULL_RTX); record_content (base, NULL_RTX);
base = gen_rtx_PLUS (HImode, base, GEN_INT (addend)); 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) if (need_es)
{ {
m = change_address (m, GET_MODE (m), gen_es_addr (base)); m = change_address (m, GET_MODE (m), gen_es_addr (base));
...@@ -2566,10 +2738,6 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before) ...@@ -2566,10 +2738,6 @@ transcode_memory_rtx (rtx m, rtx newbase, rtx before)
} }
else else
m = change_address (m, GET_MODE (m), base); m = change_address (m, GET_MODE (m), base);
#if DEBUG_ALLOC
debug_rtx (m);
fprintf (stderr, "\033[0m");
#endif
return m; return m;
} }
...@@ -2724,7 +2892,13 @@ rl78_alloc_physical_registers_op1 (rtx_insn * insn) ...@@ -2724,7 +2892,13 @@ rl78_alloc_physical_registers_op1 (rtx_insn * insn)
{ {
/* If necessary, load the operands into BC and HL. /* If necessary, load the operands into BC and HL.
Check to see if we already have OP (0) in 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)) if (MEM_P (OP (0))
&& already_contains (HL, XEXP (OP (0), 0))) && already_contains (HL, XEXP (OP (0), 0)))
{ {
...@@ -3811,6 +3985,311 @@ static bool rl78_rtx_costs (rtx x, ...@@ -3811,6 +3985,311 @@ static bool rl78_rtx_costs (rtx x,
} }
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;
}
#undef TARGET_UNWIND_WORD_MODE #undef TARGET_UNWIND_WORD_MODE
#define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode #define TARGET_UNWIND_WORD_MODE rl78_unwind_word_mode
...@@ -3820,7 +4299,111 @@ rl78_unwind_word_mode (void) ...@@ -3820,7 +4299,111 @@ rl78_unwind_word_mode (void)
return HImode; return HImode;
} }
#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;
}
struct gcc_target targetm = TARGET_INITIALIZER; struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rl78.h" #include "gt-rl78.h"
...@@ -134,7 +134,8 @@ ...@@ -134,7 +134,8 @@
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 #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_PRE_DECCREMENT 0
#define HAVE_POST_INCREMENT 0 #define HAVE_POST_INCREMENT 0
...@@ -241,6 +242,8 @@ enum reg_class ...@@ -241,6 +242,8 @@ enum reg_class
"ALL_REGS" \ "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 \ #define REG_CLASS_CONTENTS \
{ \ { \
{ 0x00000000, 0x00000000 }, /* No registers, */ \ { 0x00000000, 0x00000000 }, /* No registers, */ \
...@@ -424,6 +427,16 @@ typedef unsigned int CUMULATIVE_ARGS; ...@@ -424,6 +427,16 @@ typedef unsigned int CUMULATIVE_ARGS;
fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) 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) \ #define ASM_OUTPUT_ALIGN(STREAM, LOG) \
do \ do \
{ \ { \
......
...@@ -53,3 +53,7 @@ Enable assembler and linker relaxation. Enabled by default at -Os. ...@@ -53,3 +53,7 @@ Enable assembler and linker relaxation. Enabled by default at -Os.
mg10 mg10
Target Mask(G10) Report Target Mask(G10) Report
Target the RL78/G10 series Target the RL78/G10 series
mes0
Target Mask(ES0)
Assume ES is zero throughout program execution, use ES: for read-only data.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment