From 72ed1126861875a4fae0d75f994e35f1b79509bd Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 16 Apr 2015 07:57:56 +0000 Subject: rl78-opts.h (enum rl78_mul_types): Add MUL_G14 and MUL_UNINIT. * config/rl78/rl78-opts.h (enum rl78_mul_types): Add MUL_G14 and MUL_UNINIT. (enum rl78_cpu_type): New. * config/rl78/rl78-virt.md (attr valloc): Add divhi and divsi. (umulhi3_shift_virt): Remove m constraint from operand 1. (umulqihi3_virt): Likewise. * config/rl78/rl78.c (rl78_option_override): Add code to process -mcpu and -mmul options. (rl78_alloc_physical_registers): Add code to handle divhi and divsi valloc attributes. (set_origin): Likewise. * config/rl78/rl78.h (RL78_MUL_G14): Define. (TARGET_G10, TARGET_G13, TARGET_G14): Define. (TARGET_CPU_CPP_BUILTINS): Define __RL78_MUL_xxx__ and __RL78_Gxx__. (ASM_SPEC): Pass -mcpu on to assembler. * config/rl78/rl78.md (mulqi3): Add a clobber of AX. (mulqi3_rl78): Likewise. (mulhi3_g13): Likewise. (mulhi3): Generate the G13 or G14 versions of the insn directly. (mulsi3): Likewise. (mulhi3_g14): Add clobbers of AX and BC. (mulsi3_g14): Likewise. (mulsi3_g13): Likewise. (udivmodhi4, udivmodhi4_g14, udivmodsi4): New patterns. (udivmodsi4_g14, udivmodsi4_g13): New patterns. * config/rl78/rl78.opt (mmul): Initialise value to RL78_MUL_UNINIT. (mcpu): New option. (m13, m14, mrl78): New option aliases. * config/rl78/t-rl78 (MULTILIB_OPTIONS): Add mg13 and mg14. (MULTILIB_DIRNAMES): Add g13 and g14. * doc/invoke.texi: Document -mcpu and -mmul options. * config/rl78/divmodhi.S: Add G14 and G13 versions of the __divhi3 and __modhi3 functions. * config/rl78/divmodso.S: Add G14 and G13 versions of the __divsi3, __udivsi3, __modsi3 and __umodsi3 functions. From-SVN: r222142 --- gcc/config/rl78/rl78-opts.h | 12 +- gcc/config/rl78/rl78-virt.md | 6 +- gcc/config/rl78/rl78.c | 104 ++++++++++++++- gcc/config/rl78/rl78.h | 35 +++-- gcc/config/rl78/rl78.md | 302 +++++++++++++++++++++++++++++++++++++++---- gcc/config/rl78/rl78.opt | 48 ++++++- gcc/config/rl78/t-rl78 | 6 +- 7 files changed, 466 insertions(+), 47 deletions(-) (limited to 'gcc/config/rl78') diff --git a/gcc/config/rl78/rl78-opts.h b/gcc/config/rl78/rl78-opts.h index 8d98d8d..6fa54cc 100644 --- a/gcc/config/rl78/rl78-opts.h +++ b/gcc/config/rl78/rl78-opts.h @@ -24,7 +24,17 @@ enum rl78_mul_types { MUL_NONE, MUL_RL78, - MUL_G13 + MUL_G13, + MUL_G14, + MUL_UNINIT +}; + +enum rl78_cpu_types +{ + CPU_G10, + CPU_G13, + CPU_G14, + CPU_UNINIT }; #endif diff --git a/gcc/config/rl78/rl78-virt.md b/gcc/config/rl78/rl78-virt.md index e90e156..c70beae 100644 --- a/gcc/config/rl78/rl78-virt.md +++ b/gcc/config/rl78/rl78-virt.md @@ -28,7 +28,7 @@ ;; instruction - op1 is of the form "a = op(b)", op2 is "a = b op c" ;; etc. -(define_attr "valloc" "op1,op2,ro1,cmp,umul,macax" +(define_attr "valloc" "op1,op2,ro1,cmp,umul,macax,divhi,divsi" (const_string "op2")) ;;---------- Moving ------------------------ @@ -113,7 +113,7 @@ ) (define_insn "*umulhi3_shift_virt" - [(set (match_operand:HI 0 "register_operand" "=vm") + [(set (match_operand:HI 0 "register_operand" "=v") (mult:HI (match_operand:HI 1 "rl78_nonfar_operand" "%vim") (match_operand:HI 2 "rl78_24_operand" "Ni")))] "rl78_virt_insns_ok () && !TARGET_G10" @@ -122,7 +122,7 @@ ) (define_insn "*umulqihi3_virt" - [(set (match_operand:HI 0 "register_operand" "=vm") + [(set (match_operand:HI 0 "register_operand" "=v") (mult:HI (zero_extend:HI (match_operand:QI 1 "rl78_nonfar_operand" "%vim")) (zero_extend:HI (match_operand:QI 2 "general_operand" "vim"))))] "rl78_virt_insns_ok () && !TARGET_G10" diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index a9d5f5a..6469804 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -377,6 +377,48 @@ rl78_option_override (void) && strcmp (lang_hooks.name, "GNU GIMPLE")) /* Address spaces are currently only supported by C. */ error ("-mes0 can only be used with C"); + + switch (rl78_cpu_type) + { + case CPU_UNINIT: + rl78_cpu_type = CPU_G14; + if (rl78_mul_type == MUL_UNINIT) + rl78_mul_type = MUL_NONE; + break; + + case CPU_G10: + switch (rl78_mul_type) + { + case MUL_UNINIT: rl78_mul_type = MUL_NONE; break; + case MUL_NONE: break; + case MUL_G13: error ("-mmul=g13 cannot be used with -mcpu=g10"); break; + case MUL_G14: error ("-mmul=g14 cannot be used with -mcpu=g10"); break; + } + break; + + case CPU_G13: + switch (rl78_mul_type) + { + case MUL_UNINIT: rl78_mul_type = MUL_G13; break; + case MUL_NONE: break; + case MUL_G13: break; + /* The S2 core does not have mul/div instructions. */ + case MUL_G14: error ("-mmul=g14 cannot be used with -mcpu=g13"); break; + } + break; + + case CPU_G14: + switch (rl78_mul_type) + { + case MUL_UNINIT: rl78_mul_type = MUL_G14; break; + case MUL_NONE: break; + case MUL_G14: break; + /* The G14 core does not have the hardware multiply peripheral used by the + G13 core, hence you cannot use G13 multipliy routines on G14 hardware. */ + case MUL_G13: error ("-mmul=g13 cannot be used with -mcpu=g14"); break; + } + break; + } } /* Most registers are 8 bits. Some are 16 bits because, for example, @@ -3514,6 +3556,18 @@ rl78_alloc_physical_registers (void) record_content (BC, NULL_RTX); record_content (DE, NULL_RTX); } + else if (valloc_method == VALLOC_DIVHI) + { + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + } + else if (valloc_method == VALLOC_DIVSI) + { + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + record_content (DE, NULL_RTX); + record_content (HL, NULL_RTX); + } if (insn_ok_now (insn)) continue; @@ -3541,6 +3595,7 @@ rl78_alloc_physical_registers (void) break; case VALLOC_UMUL: rl78_alloc_physical_registers_umul (insn); + record_content (AX, NULL_RTX); break; case VALLOC_MACAX: /* Macro that clobbers AX. */ @@ -3549,6 +3604,18 @@ rl78_alloc_physical_registers (void) record_content (BC, NULL_RTX); record_content (DE, NULL_RTX); break; + case VALLOC_DIVSI: + rl78_alloc_address_registers_div (insn); + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + record_content (DE, NULL_RTX); + record_content (HL, NULL_RTX); + break; + case VALLOC_DIVHI: + rl78_alloc_address_registers_div (insn); + record_content (AX, NULL_RTX); + record_content (BC, NULL_RTX); + break; default: gcc_unreachable (); } @@ -3863,6 +3930,37 @@ set_origin (rtx pat, rtx_insn * insn, int * origins, int * age) age[i] = 0; } } + else if (get_attr_valloc (insn) == VALLOC_DIVHI) + { + if (dump_file) + fprintf (dump_file, "Resetting origin of AX/DE for DIVHI pattern.\n"); + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (i == A_REG + || i == X_REG + || i == D_REG + || i == E_REG + || origins[i] == A_REG + || origins[i] == X_REG + || origins[i] == D_REG + || origins[i] == E_REG) + { + origins[i] = i; + age[i] = 0; + } + } + else if (get_attr_valloc (insn) == VALLOC_DIVSI) + { + if (dump_file) + fprintf (dump_file, "Resetting origin of AX/BC/DE/HL for DIVSI pattern.\n"); + + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) + if (i <= 7 || origins[i] <= 7) + { + origins[i] = i; + age[i] = 0; + } + } if (GET_CODE (src) == ASHIFT || GET_CODE (src) == ASHIFTRT @@ -4087,7 +4185,7 @@ rl78_rtx_costs (rtx x, switch (code) { case MULT: - if (RL78_MUL_RL78) + if (RL78_MUL_G14) *total = COSTS_N_INSNS (14); else if (RL78_MUL_G13) *total = COSTS_N_INSNS (29); @@ -4407,7 +4505,7 @@ rl78_insert_attributes (tree decl, tree *attributes ATTRIBUTE_UNUSED) 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); } } @@ -4503,7 +4601,7 @@ rl78_flags_already_set (rtx op, rtx operand) { if (LABEL_P (insn)) break; - + if (! INSN_P (insn)) continue; diff --git a/gcc/config/rl78/rl78.h b/gcc/config/rl78/rl78.h index caa7f7f..066b0d1 100644 --- a/gcc/config/rl78/rl78.h +++ b/gcc/config/rl78/rl78.h @@ -20,20 +20,32 @@ #define RL78_MUL_NONE (rl78_mul_type == MUL_NONE) -#define RL78_MUL_RL78 (rl78_mul_type == MUL_RL78) #define RL78_MUL_G13 (rl78_mul_type == MUL_G13) +#define RL78_MUL_G14 (rl78_mul_type == MUL_G14) + +#define TARGET_G10 (rl78_cpu_type == CPU_G10) +#define TARGET_G13 (rl78_cpu_type == CPU_G13) +#define TARGET_G14 (rl78_cpu_type == CPU_G14) #define TARGET_CPU_CPP_BUILTINS() \ do \ { \ builtin_define ("__RL78__"); \ builtin_assert ("cpu=RL78"); \ - if (RL78_MUL_RL78) \ - builtin_define ("__RL78_MUL_RL78__"); \ - if (RL78_MUL_G13) \ + \ + if (RL78_MUL_NONE) \ + builtin_define ("__RL78_MUL_NONE__"); \ + else if (RL78_MUL_G13) \ builtin_define ("__RL78_MUL_G13__"); \ + else if (RL78_MUL_G14) \ + builtin_define ("__RL78_MUL_G14__"); \ + \ if (TARGET_G10) \ builtin_define ("__RL78_G10__"); \ + else if (TARGET_G13) \ + builtin_define ("__RL78_G13__"); \ + else if (TARGET_G14) \ + builtin_define ("__RL78_G14__"); \ } \ while (0) @@ -46,7 +58,14 @@ #undef ASM_SPEC #define ASM_SPEC "\ %{mrelax:-relax} \ -%{mg10} \ +%{mg10:--mg10} \ +%{mg13:--mg13} \ +%{mg14:--mg14} \ +%{mrl78:--mg14} \ +%{mcpu=g10:--mg10} \ +%{mcpu=g13:--mg13} \ +%{mcpu=g14:--mg14} \ +%{mcpu=rl78:--mg14} \ " #undef LINK_SPEC @@ -160,11 +179,11 @@ */ #define REGISTER_NAMES \ { \ - "x", "a", "c", "b", "e", "d", "l", "h", \ - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ + "x", "a", "c", "b", "e", "d", "l", "h", \ + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \ - "sp", "ap", "psw", "es", "cs" \ + "sp", "ap", "psw", "es", "cs" \ } #define ADDITIONAL_REGISTER_NAMES \ diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md index 258c139..2ea788e 100644 --- a/gcc/config/rl78/rl78.md +++ b/gcc/config/rl78/rl78.md @@ -288,10 +288,13 @@ ) (define_expand "mulqi3" - [(set (match_operand:QI 0 "register_operand") - (mult:QI (match_operand:QI 1 "general_operand") - (match_operand:QI 2 "nonmemory_operand"))) - ] + [(parallel + [(set (match_operand:QI 0 "register_operand") + (mult:QI (match_operand:QI 1 "general_operand") + (match_operand:QI 2 "nonmemory_operand"))) + (clobber (reg:HI AX_REG)) + ]) + ] "" ; mulu supported by all targets "" ) @@ -302,7 +305,13 @@ (match_operand:HI 2 "nonmemory_operand"))) ] "! RL78_MUL_NONE" - "" + { + if (RL78_MUL_G14) + emit_insn (gen_mulhi3_g14 (operands[0], operands[1], operands[2])); + else /* RL78_MUL_G13 */ + emit_insn (gen_mulhi3_g13 (operands[0], operands[1], operands[2])); + DONE; + } ) (define_expand "mulsi3" @@ -311,14 +320,21 @@ (match_operand:SI 2 "nonmemory_operand"))) ] "! RL78_MUL_NONE" - "" + { + if (RL78_MUL_G14) + emit_insn (gen_mulsi3_g14 (operands[0], operands[1], operands[2])); + else /* RL78_MUL_G13 */ + emit_insn (gen_mulsi3_g13 (operands[0], operands[1], operands[2])); + DONE; + } ) (define_insn "*mulqi3_rl78" [(set (match_operand:QI 0 "register_operand" "=&v") (mult:QI (match_operand:QI 1 "general_operand" "viU") (match_operand:QI 2 "general_operand" "vi"))) - ] + (clobber (reg:HI AX_REG)) + ] "" ; mulu supported by all targets "; mulqi macro %0 = %1 * %2 mov a, %h1 @@ -328,31 +344,34 @@ mov a, x mov %h0, a ; end of mulqi macro" -;; [(set_attr "valloc" "macax")] + [(set_attr "valloc" "macax")] ) -(define_insn "*mulhi3_rl78" +(define_insn "mulhi3_g14" [(set (match_operand:HI 0 "register_operand" "=&v") (mult:HI (match_operand:HI 1 "general_operand" "viU") (match_operand:HI 2 "general_operand" "vi"))) - ] - "RL78_MUL_RL78" - "; mulhi macro %0 = %1 * %2 + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "RL78_MUL_G14" + "; G14 mulhi macro %0 = %1 * %2 movw ax, %h1 movw bc, %h2 mulhu ; bcax = bc * ax movw %h0, ax ; end of mulhi macro" -;; [(set_attr "valloc" "macax")] + [(set_attr "valloc" "macax")] ) -(define_insn "*mulhi3_g13" +(define_insn "mulhi3_g13" [(set (match_operand:HI 0 "register_operand" "=&v") (mult:HI (match_operand:HI 1 "general_operand" "viU") (match_operand:HI 2 "general_operand" "vi"))) - ] + (clobber (reg:HI AX_REG)) + ] "RL78_MUL_G13" - "; mulhi macro %0 = %1 * %2 + "; G13 mulhi macro %0 = %1 * %2 mov a, #0x00 mov !0xf00e8, a ; MDUC movw ax, %h1 @@ -363,19 +382,21 @@ movw ax, 0xffff6 ; MDBL movw %h0, ax ; end of mulhi macro" -;; [(set_attr "valloc" "umul")] + [(set_attr "valloc" "macax")] ) ;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it ;; because we're only using the lower 16 bits (which is the upper 16 ;; bits of the result). -(define_insn "mulsi3_rl78" +(define_insn "mulsi3_g14" [(set (match_operand:SI 0 "register_operand" "=&v") (mult:SI (match_operand:SI 1 "general_operand" "viU") (match_operand:SI 2 "general_operand" "vi"))) - ] - "RL78_MUL_RL78" - "; mulsi macro %0 = %1 * %2 + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] + "RL78_MUL_G14" + "; G14 mulsi macro %0 = %1 * %2 movw ax, %h1 movw bc, %h2 MULHU ; bcax = bc * ax @@ -403,9 +424,11 @@ [(set (match_operand:SI 0 "register_operand" "=&v") (mult:SI (match_operand:SI 1 "general_operand" "viU") (match_operand:SI 2 "general_operand" "viU"))) - ] + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + ] "RL78_MUL_G13" - "; mulsi macro %0 = %1 * %2 + "; G13 mulsi macro %0 = %1 * %2 mov a, #0x00 mov !0xf00e8, a ; MDUC movw ax, %h1 @@ -441,3 +464,236 @@ ; end of mulsi macro" [(set_attr "valloc" "macax")] ) + +(define_expand "udivmodhi4" + [(parallel + [(set (match_operand:HI 0 "register_operand") + (udiv:HI (match_operand:HI 1 "register_operand") + (match_operand:HI 2 "register_operand"))) + (set (match_operand:HI 3 "register_operand") + (umod:HI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI DE_REG)) + ]) + ] + "RL78_MUL_G14" + "" +) + +(define_insn "*udivmodhi4_g14" + [(set (match_operand:HI 0 "register_operand" "=v") + (udiv:HI (match_operand:HI 1 "register_operand" "v") + (match_operand:HI 2 "register_operand" "v"))) + (set (match_operand:HI 3 "register_operand" "=v") + (umod:HI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI DE_REG)) + ] + "RL78_MUL_G14" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G14 udivhi macro %0 = %1 / %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; ax = ax / de \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + ; end of udivhi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G14 umodhi macro %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; de = ax %% de \n\ + pop psw ; Restore saved interrupt status \n\ + movw ax, de \n\ + movw %h3, ax \n\ + ; end of umodhi macro"; + else + return "; G14 udivmodhi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw de, %h2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divhu ; ax = ax / de, de = ax %% de \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, de \n\ + movw %h3, ax \n\ + ; end of udivmodhi macro"; + } + [(set_attr "valloc" "divhi")] +) + +(define_expand "udivmodsi4" + [(parallel + [(set (match_operand:SI 0 "register_operand") + (udiv:SI (match_operand:SI 1 "register_operand") + (match_operand:SI 2 "register_operand"))) + (set (match_operand:SI 3 "register_operand") + (umod:SI (match_dup 1) (match_dup 2))) + ]) + ] + "! RL78_MUL_NONE && ! optimize_size" + { + if (RL78_MUL_G14) + emit_insn (gen_udivmodsi4_g14 (operands[0], operands[1], operands[2], operands[3])); + else /* RL78_MUL_G13 */ + emit_insn (gen_udivmodsi4_g13 (operands[0], operands[1], operands[2], operands[3])); + DONE; + } +) + +(define_insn "udivmodsi4_g14" + [(set (match_operand:SI 0 "register_operand" "=v") + (udiv:SI (match_operand:SI 1 "register_operand" "v") + (match_operand:SI 2 "register_operand" "v"))) + (set (match_operand:SI 3 "register_operand" "=v") + (umod:SI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + (clobber (reg:HI BC_REG)) + (clobber (reg:HI DE_REG)) + (clobber (reg:HI HL_REG)) + ] + "RL78_MUL_G14" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G14 udivsi macro %0 = %1 / %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; bcax = bcax / hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, bc \n\ + movw %H0, ax \n\ + ; end of udivsi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G14 umodsi macro %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; hlde = bcax %% hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw ax, de \n\ + movw %h3, ax \n\ + movw ax, hl \n\ + movw %H3, ax \n\ + ; end of umodsi macro"; + else + return "; G14 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + movw ax, %h1 \n\ + movw bc, %H1 \n\ + movw de, %h2 \n\ + movw hl, %H2 \n\ + push psw ; Save the current interrupt status \n\ + di ; Disable interrupts. See Renesas Technical update TN-RL*-A025B/E \n\ + divwu ; bcax = bcax / hlde, hlde = bcax %% hlde \n\ + pop psw ; Restore saved interrupt status \n\ + movw %h0, ax \n\ + movw ax, bc \n\ + movw %H0, ax \n\ + movw ax, de \n\ + movw %h3, ax \n\ + movw ax, hl \n\ + movw %H3, ax \n\ + ; end of udivmodsi macro"; + } + [(set_attr "valloc" "divsi")] +) + +;; Warning: these values match the silicon not the documentation. +;; 0xFFFF0 is MDAL. 0xFFFF2 is MDAH. +;; 0xFFFF6 is MDBL. 0xFFFF4 is MDBH. +;; 0xF00E0 is MDCL. 0xF00E2 is MDCH. +;; 0xF00E8 is MDUC. + +(define_insn "udivmodsi4_g13" + [(set (match_operand:SI 0 "register_operand" "=v") + (udiv:SI (match_operand:SI 1 "register_operand" "v") + (match_operand:SI 2 "register_operand" "v"))) + (set (match_operand:SI 3 "register_operand" "=v") + (umod:SI (match_dup 1) (match_dup 2))) + (clobber (reg:HI AX_REG)) + ] + "RL78_MUL_G13" + { + if (find_reg_note (insn, REG_UNUSED, operands[3])) + return "; G13 udivsi macro %0 = %1 / %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, 0xffff0 ; Read the quotient \n\ + movw %h0, ax \n\ + movw ax, 0xffff2 \n\ + movw %H0, ax \n\ + ; end of udivsi macro"; + else if (find_reg_note (insn, REG_UNUSED, operands[0])) + return "; G13 umodsi macro %3 = %1 %% %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, !0xf00e0 ; Read the remainder \n\ + movw %h3, ax \n\ + movw ax, !0xf00e2 \n\ + movw %H3, ax \n\ + ; end of umodsi macro"; + else + return "; G13 udivmodsi macro %0 = %1 / %2 and %3 = %1 %% %2 \n\ + mov a, #0xC0 ; Set DIVMODE=1 and MACMODE=1 \n\ + mov !0xf00e8, a ; This preps the peripheral for division without interrupt generation \n\ + movw ax, %H1 \n\ + movw 0xffff2, ax ; MDAH \n\ + movw ax, %h1 \n\ + movw 0xffff0, ax ; MDAL \n\ + movw ax, %H2 \n\ + movw 0xffff4, ax ; MDBH \n\ + movw ax, %h2 \n\ + movw 0xffff6, ax ; MDBL \n\ + mov a, #0xC1 ; Set the DIVST bit in MDUC \n\ + mov !0xf00e8, a ; This starts the division op \n\ +1: mov a, !0xf00e8 ; Wait 16 clocks or until DIVST is clear \n\ + bt a.0, $1b \n\ + movw ax, 0xffff0 ; Read the quotient \n\ + movw %h0, ax \n\ + movw ax, 0xffff2 \n\ + movw %H0, ax \n\ + movw ax, !0xf00e0 ; Read the remainder \n\ + movw %h3, ax \n\ + movw ax, !0xf00e2 \n\ + movw %H3, ax \n\ + ; end of udivmodsi macro"; + } + [(set_attr "valloc" "macax")] +) diff --git a/gcc/config/rl78/rl78.opt b/gcc/config/rl78/rl78.opt index 1e4c14c..80b894a 100644 --- a/gcc/config/rl78/rl78.opt +++ b/gcc/config/rl78/rl78.opt @@ -27,20 +27,23 @@ Target Report Use the simulator runtime. mmul= -Target RejectNegative Joined Var(rl78_mul_type) Report Tolower Enum(rl78_mul_types) Init(MUL_NONE) -Select hardware or software multiplication support. +Target RejectNegative Joined Var(rl78_mul_type) Report Tolower Enum(rl78_mul_types) Init(MUL_UNINIT) +Selects the type of hardware multiplication and division to use (none/g13/g14). Enum Name(rl78_mul_types) Type(enum rl78_mul_types) EnumValue -Enum(rl78_mul_types) String(none) Value(MUL_NONE) +Enum(rl78_mul_types) String(g10) Value(MUL_NONE) EnumValue -Enum(rl78_mul_types) String(rl78) Value(MUL_RL78) +Enum(rl78_mul_types) String(g13) Value(MUL_G13) EnumValue -Enum(rl78_mul_types) String(g13) Value(MUL_G13) +Enum(rl78_mul_types) String(g14) Value(MUL_G14) + +EnumValue +Enum(rl78_mul_types) String(rl78) Value(MUL_G14) mallregs Target Mask(ALLREGS) Report Optimization @@ -50,9 +53,40 @@ mrelax Target Report Optimization Enable assembler and linker relaxation. Enabled by default at -Os. +mcpu= +Target RejectNegative Joined Var(rl78_cpu_type) Report ToLower Enum(rl78_cpu_types) Init(CPU_UNINIT) +Selects the type of RL78 core being targeted (g10/g13/g14). The default is the G14. If set, also selects the hardware multiply support to be used. + +Enum +Name(rl78_cpu_types) Type(enum rl78_cpu_types) + +EnumValue +Enum(rl78_cpu_types) String(g10) Value(CPU_G10) + +EnumValue +Enum(rl78_cpu_types) String(g13) Value(CPU_G13) + +EnumValue +Enum(rl78_cpu_types) String(g14) Value(CPU_G14) + +EnumValue +Enum(rl78_cpu_types) String(rl78) Value(CPU_G14) + mg10 -Target Mask(G10) Report -Target the RL78/G10 series +Target RejectNegative Report Alias(mcpu=, g10) +Alias for -mcpu=g10 + +mg13 +Target RejectNegative Report Alias(mcpu=, g13) +Alias for -mcpu=g13 + +mg14 +Target RejectNegative Report Alias(mcpu=, g14) +Alias for -mcpu=g14 + +mrl78 +Target RejectNegative Report Alias(mcpu=, g14) +Alias for -mcpu=g14 mes0 Target Mask(ES0) diff --git a/gcc/config/rl78/t-rl78 b/gcc/config/rl78/t-rl78 index 2628855..bd8fab4 100644 --- a/gcc/config/rl78/t-rl78 +++ b/gcc/config/rl78/t-rl78 @@ -23,5 +23,7 @@ rl78-c.o: $(srcdir)/config/rl78/rl78-c.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_H) # Enable multilibs: -MULTILIB_OPTIONS = mg10 -MULTILIB_DIRNAMES = g10 +MULTILIB_OPTIONS = mg10/mg13/mg14 +MULTILIB_DIRNAMES = g10 g13 g14 + +MULTILIB_MATCHES = mg10=mcpu?g10 mg13=mcpu?g13 mg14=mcpu?g14 mg14=mcpu?rl78 -- cgit v1.1