diff options
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/bfin/bfin-protos.h | 11 | ||||
-rw-r--r-- | gcc/config/bfin/bfin.c | 94 | ||||
-rw-r--r-- | gcc/config/bfin/bfin.md | 26 |
4 files changed, 111 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44836d5..2a0f5ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2008-10-29 Bernd Schmidt <bernd.schmidt@analog.com> + + * config/bfin/bfin-protos.h (WA_05000257, WA_05000283, WA_05000315, + ENABLE_WA_05000257, ENABLE_WA_05000283, ENABLE_WA_05000315): New. + * config/bfin/bfin.c (bfin_cpus): Add these workaround bits as + appropriate. + (must_save_p): For some workarounds, interrupts need to clobber a + P register. + (expand_prologue_reg_save, expand_epilogue_reg_restore): Save LC0 + and LC1 for WA_05000257. + (expand_interrupt_handler_prologue): Add dummy read of CHIPID for + WA_05000283 and WA_05000315. + * config/bfin/bfin.md (UNSPEC_VOLATILE_DUMMY): New constant. + (movbi): Add alternative to set CC to 1; improve code for setting + CC to 0. + (dummy_load): New pattern. + 2008-10-29 Jakub Jelinek <jakub@redhat.com> PR middle-end/37870 diff --git a/gcc/config/bfin/bfin-protos.h b/gcc/config/bfin/bfin-protos.h index 6d6ffd2..523c673 100644 --- a/gcc/config/bfin/bfin-protos.h +++ b/gcc/config/bfin/bfin-protos.h @@ -75,6 +75,17 @@ extern unsigned int bfin_workarounds; #define ENABLE_WA_RETS \ (bfin_workarounds & WA_RETS) +#define WA_05000257 0x00000040 +#define ENABLE_WA_05000257 \ + (bfin_workarounds & WA_05000257) + +#define WA_05000283 0x00000010 +#define ENABLE_WA_05000283 \ + (bfin_workarounds & WA_05000283) + +#define WA_05000315 0x00000020 +#define ENABLE_WA_05000315 \ + (bfin_workarounds & WA_05000315) #define Mmode enum machine_mode diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 5a289df..3f3f9dc 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -175,68 +175,83 @@ struct bfin_cpu bfin_cpus[] = {"bf531", BFIN_CPU_BF531, 0x0006, WA_SPECULATIVE_LOADS}, {"bf531", BFIN_CPU_BF531, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, {"bf531", BFIN_CPU_BF531, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf531", BFIN_CPU_BF531, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf532", BFIN_CPU_BF532, 0x0006, WA_SPECULATIVE_LOADS}, {"bf532", BFIN_CPU_BF532, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, {"bf532", BFIN_CPU_BF532, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf532", BFIN_CPU_BF532, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf533", BFIN_CPU_BF533, 0x0006, WA_SPECULATIVE_LOADS}, {"bf533", BFIN_CPU_BF533, 0x0005, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000315}, {"bf533", BFIN_CPU_BF533, 0x0004, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf533", BFIN_CPU_BF533, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf534", BFIN_CPU_BF534, 0x0003, WA_SPECULATIVE_LOADS | WA_RETS}, {"bf534", BFIN_CPU_BF534, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf534", BFIN_CPU_BF534, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf536", BFIN_CPU_BF536, 0x0003, WA_SPECULATIVE_LOADS | WA_RETS}, {"bf536", BFIN_CPU_BF536, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf536", BFIN_CPU_BF536, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf537", BFIN_CPU_BF537, 0x0003, WA_SPECULATIVE_LOADS | WA_RETS}, {"bf537", BFIN_CPU_BF537, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf537", BFIN_CPU_BF537, 0x0001, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf538", BFIN_CPU_BF538, 0x0005, WA_SPECULATIVE_LOADS}, {"bf538", BFIN_CPU_BF538, 0x0004, WA_SPECULATIVE_LOADS | WA_RETS}, {"bf538", BFIN_CPU_BF538, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000315}, {"bf538", BFIN_CPU_BF538, 0x0002, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS | WA_05000283 | WA_05000257 | WA_05000315}, {"bf539", BFIN_CPU_BF539, 0x0005, WA_SPECULATIVE_LOADS}, {"bf539", BFIN_CPU_BF539, 0x0004, WA_SPECULATIVE_LOADS | WA_RETS}, {"bf539", BFIN_CPU_BF539, 0x0003, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000315}, {"bf539", BFIN_CPU_BF539, 0x0002, - WA_SPECULATIVE_LOADS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf542", BFIN_CPU_BF542, 0x0002, WA_SPECULATIVE_LOADS}, @@ -273,11 +288,14 @@ struct bfin_cpu bfin_cpus[] = {"bf549", BFIN_CPU_BF549, 0x0000, WA_SPECULATIVE_LOADS | WA_RETS}, - {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS}, + {"bf561", BFIN_CPU_BF561, 0x0005, WA_RETS + | WA_05000283 | WA_05000315}, {"bf561", BFIN_CPU_BF561, 0x0003, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {"bf561", BFIN_CPU_BF561, 0x0002, - WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS}, + WA_SPECULATIVE_LOADS | WA_SPECULATIVE_SYNCS | WA_RETS + | WA_05000283 | WA_05000257 | WA_05000315}, {NULL, 0, 0, 0} }; @@ -457,6 +475,9 @@ must_save_p (bool is_inthandler, unsigned regno) return ((df_regs_ever_live_p (regno) && !fixed_regs[regno] && (is_inthandler || !call_used_regs[regno])) + || (is_inthandler + && (ENABLE_WA_05000283 || ENABLE_WA_05000315) + && regno == REG_P5) || (!TARGET_FDPIC && regno == PIC_OFFSET_TABLE_REGNUM && (crtl->uses_pic_offset_table @@ -550,10 +571,12 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler) rtx insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT)); RTX_FRAME_RELATED_P (insn) = 1; - if (! current_function_is_leaf - || cfun->machine->has_hardware_loops - || cfun->machine->has_loopreg_clobber) - for (dregno = REG_LT0; dregno <= REG_LB1; dregno++) + for (dregno = REG_LT0; dregno <= REG_LB1; dregno++) + if (! current_function_is_leaf + || cfun->machine->has_hardware_loops + || cfun->machine->has_loopreg_clobber + || (ENABLE_WA_05000257 + && (dregno == REG_LC0 || dregno == REG_LC1))) { insn = emit_move_insn (predec, gen_rtx_REG (SImode, dregno)); RTX_FRAME_RELATED_P (insn) = 1; @@ -728,10 +751,11 @@ expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler) } if (saveall || is_inthandler) { - if (! current_function_is_leaf - || cfun->machine->has_hardware_loops - || cfun->machine->has_loopreg_clobber) - for (regno = REG_LB1; regno >= REG_LT0; regno--) + for (regno = REG_LB1; regno >= REG_LT0; regno--) + if (! current_function_is_leaf + || cfun->machine->has_hardware_loops + || cfun->machine->has_loopreg_clobber + || (ENABLE_WA_05000257 && (regno == REG_LC0 || regno == REG_LC1))) emit_move_insn (gen_rtx_REG (SImode, regno), postinc); emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc); @@ -1150,6 +1174,16 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all) all = true; expand_prologue_reg_save (spreg, all, true); + if (ENABLE_WA_05000283 || ENABLE_WA_05000315) + { + rtx chipid = GEN_INT (trunc_int_for_mode (0xFFC00014, SImode)); + rtx p5reg = gen_rtx_REG (Pmode, REG_P5); + emit_insn (gen_movbi (bfin_cc_rtx, const1_rtx)); + emit_insn (gen_movsi_high (p5reg, chipid)); + emit_insn (gen_movsi_low (p5reg, p5reg, chipid)); + emit_insn (gen_dummy_load (p5reg, bfin_cc_rtx)); + } + if (lookup_attribute ("nesting", attrs)) { rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md index 9f3289d..3199666 100644 --- a/gcc/config/bfin/bfin.md +++ b/gcc/config/bfin/bfin.md @@ -145,7 +145,8 @@ (UNSPEC_VOLATILE_CSYNC 1) (UNSPEC_VOLATILE_SSYNC 2) (UNSPEC_VOLATILE_LOAD_FUNCDESC 3) - (UNSPEC_VOLATILE_STORE_EH_HANDLER 4)]) + (UNSPEC_VOLATILE_STORE_EH_HANDLER 4) + (UNSPEC_VOLATILE_DUMMY 5)]) (define_constants [(MACFLAG_NONE 0) @@ -458,8 +459,8 @@ }) (define_insn "movbi" - [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C") - (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0"))] + [(set (match_operand:BI 0 "nonimmediate_operand" "=x,x,d,md,C,d,C,P1") + (match_operand:BI 1 "general_operand" "x,xKs3,md,d,d,C,P0,P1"))] "" "@ @@ -469,10 +470,11 @@ B %0 = %1; CC = %1; %0 = CC; - R0 = R0 | R0; CC = AC0;" - [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,alu0") - (set_attr "length" "2,2,*,*,2,2,4") - (set_attr "seq_insns" "*,*,*,*,*,*,multi")]) + CC = R0 < R0; + CC = R0 == R0;" + [(set_attr "type" "move,mvi,mcld,mcst,compare,compare,compare,compare") + (set_attr "length" "2,2,*,*,2,2,2,2") + (set_attr "seq_insns" "*,*,*,*,*,*,*,*")]) (define_insn "movpdi" [(set (match_operand:PDI 0 "nonimmediate_operand" "=e,<,e") @@ -2826,6 +2828,16 @@ gcc_unreachable (); }) +(define_insn "dummy_load" + [(unspec_volatile [(match_operand 0 "register_operand" "a") + (match_operand 1 "register_operand" "C")] + UNSPEC_VOLATILE_DUMMY)] + "" + "if cc jump 4;\n\tr7 = [%0];" + [(set_attr "type" "misc") + (set_attr "length" "4") + (set_attr "seq_insns" "multi")]) + (define_insn "csync" [(unspec_volatile [(const_int 0)] UNSPEC_VOLATILE_CSYNC)] "" |