From f1a0afe2aa1447c2d7962f52e8e278c40ba5fe19 Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Sat, 7 Apr 2018 06:21:56 +0000 Subject: [PATCH] [NDS32] Add intrinsic functions for cache control. gcc/ * config/nds32/constants.md (unspec_volatile_element): Add cache control enum values. * config/nds32/nds32-intrinsic.c: Add cache control expand functions. * config/nds32/nds32-intrinsic.md: Add cache control patterns. * config/nds32/nds32.c (nds32_cctl_names): New. (nds32_print_operand): Handle cache control register names. * config/nds32/nds32.h (nds32_builtins): New enum values. * config/nds32/nds32_intrinsic.h: Add cache control enum types and macros. * config/nds32/nds32.md (type): Add mmu. * config/nds32/pipelines.md (simple_insn): Add mmu. From-SVN: r259205 --- gcc/ChangeLog | 14 +++++ gcc/config/nds32/constants.md | 10 +++- gcc/config/nds32/nds32-intrinsic.c | 84 ++++++++++++++++++++++++++++ gcc/config/nds32/nds32-intrinsic.md | 73 +++++++++++++++++++++++++ gcc/config/nds32/nds32.c | 63 +++++++++++++++++++++ gcc/config/nds32/nds32.h | 9 +++ gcc/config/nds32/nds32.md | 2 +- gcc/config/nds32/nds32_intrinsic.h | 85 +++++++++++++++++++++++++++++ gcc/config/nds32/pipelines.md | 2 +- 9 files changed, 339 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f989b1f6220..1f0dff3f6ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2018-04-07 Monk Chiang + + * config/nds32/constants.md (unspec_volatile_element): Add cache + control enum values. + * config/nds32/nds32-intrinsic.c: Add cache control expand functions. + * config/nds32/nds32-intrinsic.md: Add cache control patterns. + * config/nds32/nds32.c (nds32_cctl_names): New. + (nds32_print_operand): Handle cache control register names. + * config/nds32/nds32.h (nds32_builtins): New enum values. + * config/nds32/nds32_intrinsic.h: Add cache control enum types and + macros. + * config/nds32/nds32.md (type): Add mmu. + * config/nds32/pipelines.md (simple_insn): Add mmu. + 2018-04-07 Chung-Ju Wu * config/nds32/nds32.md (type): Remove call. diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md index 1a0e880dc43..92181fd850b 100644 --- a/gcc/config/nds32/constants.md +++ b/gcc/config/nds32/constants.md @@ -61,7 +61,15 @@ UNSPEC_VOLATILE_FMFCSR UNSPEC_VOLATILE_FMTCSR UNSPEC_VOLATILE_FMFCFG - + UNSPEC_VOLATILE_CCTL_L1D_INVALALL + UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL + UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL + UNSPEC_VOLATILE_CCTL_IDX_WRITE + UNSPEC_VOLATILE_CCTL_IDX_READ + UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1 + UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA + UNSPEC_VOLATILE_CCTL_IDX_WBINVAL + UNSPEC_VOLATILE_CCTL_VA_LCK UNSPEC_VOLATILE_RELAX_GROUP UNSPEC_VOLATILE_POP25_RETURN ]) diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c index c5435bb9dd4..3dc9aa29aad 100644 --- a/gcc/config/nds32/nds32-intrinsic.c +++ b/gcc/config/nds32/nds32-intrinsic.c @@ -222,6 +222,47 @@ nds32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target, return target; } +/* Expand cctl builtins. */ +static rtx +nds32_expand_cctl_builtin (enum insn_code icode, tree exp, rtx target, + bool return_p, const char *name) +{ + rtx pat; + rtx op0 = nds32_read_argument (exp, 0); + rtx op1 = nds32_read_argument (exp, 1); + int op0_num = return_p ? 1 : 0; + int op1_num = return_p ? 2 : 1; + + if (return_p) + target = nds32_legitimize_target (icode, target); + + if (!nds32_check_constant_argument (icode, op0_num, op0, name)) + return NULL_RTX; + + op0 = nds32_legitimize_argument (icode, op0_num, op0); + op1 = nds32_legitimize_argument (icode, op1_num, op1); + + /* Emit and return the new instruction. */ + if (icode == CODE_FOR_cctl_idx_write) + { + /* cctl_idx_write is three argument, + so create operand2 for cctl_idx_write pattern. */ + rtx op2 = nds32_read_argument (exp, 2); + op2 = nds32_legitimize_argument (icode, 2, op2); + pat = GEN_FCN (icode) (op0, op1, op2); + } + else if (return_p) + pat = GEN_FCN (icode) (target, op0, op1); + else + pat = GEN_FCN (icode) (op0, op1); + + if (! pat) + return NULL_RTX; + + emit_insn (pat); + return target; +} + struct builtin_description { const enum insn_code icode; @@ -280,6 +321,20 @@ static struct builtin_description bdesc_2arg[] = }; + +static struct builtin_description bdesc_cctl[] = +{ + NDS32_BUILTIN(cctl_idx_read, "cctl_idx_read", CCTL_IDX_READ) + NDS32_NO_TARGET_BUILTIN(cctl_idx_write, "cctl_idx_write", CCTL_IDX_WRITE) + NDS32_NO_TARGET_BUILTIN(cctl_va_lck, "cctl_va_lck", CCTL_VA_LCK) + NDS32_NO_TARGET_BUILTIN(cctl_idx_wbinval, + "cctl_idx_wbinval", CCTL_IDX_WBINVAL) + NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_l1, + "cctl_va_wbinval_l1", CCTL_VA_WBINVAL_L1) + NDS32_NO_TARGET_BUILTIN(cctl_va_wbinval_la, + "cctl_va_wbinval_la", CCTL_VA_WBINVAL_LA) +}; + rtx nds32_expand_builtin_impl (tree exp, rtx target, @@ -346,6 +401,15 @@ nds32_expand_builtin_impl (tree exp, return target; case NDS32_BUILTIN_SETGIE_DIS: emit_insn (gen_unspec_volatile_setgie_dis ()); + case NDS32_BUILTIN_CCTL_L1D_INVALALL: + emit_insn (gen_cctl_l1d_invalall()); + return target; + case NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL: + emit_insn (gen_cctl_l1d_wball_alvl()); + return target; + case NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL: + emit_insn (gen_cctl_l1d_wball_one_lvl()); + return target; return target; default: break; @@ -369,6 +433,10 @@ nds32_expand_builtin_impl (tree exp, if (d->code == fcode) return nds32_expand_binop_builtin (d->icode, exp, target, d->return_p); + for (i = 0, d = bdesc_cctl; i < ARRAY_SIZE (bdesc_cctl); i++, d++) + if (d->code == fcode) + return nds32_expand_cctl_builtin (d->icode, exp, target, + d->return_p, d->name); return NULL_RTX; } @@ -451,6 +519,22 @@ nds32_init_builtins_impl (void) ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN); ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS); + /* CCTL */ + ADD_NDS32_BUILTIN0 ("cctl_l1d_invalall", void, CCTL_L1D_INVALALL); + ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_alvl", void, CCTL_L1D_WBALL_ALVL); + ADD_NDS32_BUILTIN0 ("cctl_l1d_wball_one_lvl", void, CCTL_L1D_WBALL_ONE_LVL); + ADD_NDS32_BUILTIN2 ("cctl_va_lck", void, integer, ptr_uint, CCTL_VA_LCK); + ADD_NDS32_BUILTIN2 ("cctl_idx_wbinval", void, integer, unsigned, + CCTL_IDX_WBINVAL); + ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_l1", void, integer, ptr_uint, + CCTL_VA_WBINVAL_L1); + ADD_NDS32_BUILTIN2 ("cctl_va_wbinval_la", void, integer, ptr_uint, + CCTL_VA_WBINVAL_LA); + ADD_NDS32_BUILTIN2 ("cctl_idx_read", unsigned, integer, unsigned, + CCTL_IDX_READ); + ADD_NDS32_BUILTIN3 ("cctl_idx_write", void, integer, unsigned, unsigned, + CCTL_IDX_WRITE); + /* Unaligned Load/Store */ ADD_NDS32_BUILTIN1 ("unaligned_load_hw", short_unsigned, ptr_ushort, UALOAD_HW); diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md index 59aad349dc3..d9f1eb07dbe 100644 --- a/gcc/config/nds32/nds32-intrinsic.md +++ b/gcc/config/nds32/nds32-intrinsic.md @@ -162,6 +162,79 @@ [(set_attr "type" "misc")] ) + +;; CCTL + +(define_insn "cctl_l1d_invalall" + [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_INVALALL)] + "" + "cctl\tL1D_INVALALL" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_l1d_wball_alvl" + [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ALVL)] + "" + "cctl\tL1D_WBALL, alevel" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_l1d_wball_one_lvl" + [(unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_CCTL_L1D_WBALL_ONE_LVL)] + "" + "cctl\tL1D_WBALL, 1level" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_idx_read" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i") + (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_READ))] + "" + "cctl\t%0, %2, %X1" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_idx_write" + [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") + (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WRITE)] + "" + "cctl\t%1, %2, %W0" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_va_wbinval_l1" + [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") + (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_L1)] + "" + "cctl\t%1, %U0, 1level" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_va_wbinval_la" + [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") + (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_WBINVAL_LA)] + "" + "cctl\t%1, %U0, alevel" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_idx_wbinval" + [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") + (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_IDX_WBINVAL)] + "" + "cctl\t%1, %T0" + [(set_attr "type" "mmu")] +) + +(define_insn "cctl_va_lck" + [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i") + (match_operand:SI 1 "register_operand" "r")] UNSPEC_VOLATILE_CCTL_VA_LCK)] + "" + "cctl\t%1, %R0" + [(set_attr "type" "mmu")] +) ;; String Extension (define_insn "unspec_ffb" diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c index 2b52d8409bc..98835096afe 100644 --- a/gcc/config/nds32/nds32.c +++ b/gcc/config/nds32/nds32.c @@ -237,6 +237,34 @@ static const char * const nds32_intrinsic_register_names[] = "$ITB" }; +/* Define instrinsic cctl names. */ +static const char * const nds32_cctl_names[] = +{ + "L1D_VA_FILLCK", + "L1D_VA_ULCK", + "L1I_VA_FILLCK", + "L1I_VA_ULCK", + + "L1D_IX_WBINVAL", + "L1D_IX_INVAL", + "L1D_IX_WB", + "L1I_IX_INVAL", + + "L1D_VA_INVAL", + "L1D_VA_WB", + "L1D_VA_WBINVAL", + "L1I_VA_INVAL", + + "L1D_IX_RTAG", + "L1D_IX_RWD", + "L1I_IX_RTAG", + "L1I_IX_RWD", + + "L1D_IX_WTAG", + "L1D_IX_WWD", + "L1I_IX_WTAG", + "L1I_IX_WWD" +}; /* Defining register allocation order for performance. We want to allocate callee-saved registers after others. @@ -2906,6 +2934,41 @@ nds32_print_operand (FILE *stream, rtx x, int code) /* No need to handle following process, so return immediately. */ return; + case 'R': /* cctl valck */ + /* Note the cctl divide to 5 group and share the same name table. */ + if (op_value < 0 || op_value > 4) + error ("CCTL intrinsic function subtype out of range!"); + fprintf (stream, "%s", nds32_cctl_names[op_value]); + return; + + case 'T': /* cctl idxwbinv */ + /* Note the cctl divide to 5 group and share the same name table. */ + if (op_value < 0 || op_value > 4) + error ("CCTL intrinsic function subtype out of range!"); + fprintf (stream, "%s", nds32_cctl_names[op_value + 4]); + return; + + case 'U': /* cctl vawbinv */ + /* Note the cctl divide to 5 group and share the same name table. */ + if (op_value < 0 || op_value > 4) + error ("CCTL intrinsic function subtype out of range!"); + fprintf (stream, "%s", nds32_cctl_names[op_value + 8]); + return; + + case 'X': /* cctl idxread */ + /* Note the cctl divide to 5 group and share the same name table. */ + if (op_value < 0 || op_value > 4) + error ("CCTL intrinsic function subtype out of range!"); + fprintf (stream, "%s", nds32_cctl_names[op_value + 12]); + return; + + case 'W': /* cctl idxwitre */ + /* Note the cctl divide to 5 group and share the same name table. */ + if (op_value < 0 || op_value > 4) + error ("CCTL intrinsic function subtype out of range!"); + fprintf (stream, "%s", nds32_cctl_names[op_value + 16]); + return; + default : /* Unknown flag. */ output_operand_lossage ("invalid operand output code"); diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 7ec0f7c2ba1..353034eb828 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -452,6 +452,15 @@ enum nds32_builtins NDS32_BUILTIN_FFB, NDS32_BUILTIN_FFMISM, NDS32_BUILTIN_FLMISM, + NDS32_BUILTIN_CCTL_VA_LCK, + NDS32_BUILTIN_CCTL_IDX_WBINVAL, + NDS32_BUILTIN_CCTL_VA_WBINVAL_L1, + NDS32_BUILTIN_CCTL_VA_WBINVAL_LA, + NDS32_BUILTIN_CCTL_IDX_READ, + NDS32_BUILTIN_CCTL_IDX_WRITE, + NDS32_BUILTIN_CCTL_L1D_INVALALL, + NDS32_BUILTIN_CCTL_L1D_WBALL_ALVL, + NDS32_BUILTIN_CCTL_L1D_WBALL_ONE_LVL, NDS32_BUILTIN_UALOAD_HW, NDS32_BUILTIN_UALOAD_W, NDS32_BUILTIN_UALOAD_DW, diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md index 963e18a5f92..428d8164af2 100644 --- a/gcc/config/nds32/nds32.md +++ b/gcc/config/nds32/nds32.md @@ -55,7 +55,7 @@ ;; Insn type, it is used to default other attribute values. (define_attr "type" - "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,misc,\ + "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,mmu,misc,\ falu,fmuls,fmuld,fmacs,fmacd,fdivs,fdivd,fsqrts,fsqrtd,fcmp,fabs,fcpy,fcmov,fmfsr,fmfdr,fmtsr,fmtdr,fload,fstore" (const_string "unknown")) diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h index 523e7f571ed..24f6516d16e 100644 --- a/gcc/config/nds32/nds32_intrinsic.h +++ b/gcc/config/nds32/nds32_intrinsic.h @@ -185,6 +185,46 @@ enum nds32_intrinsic_registers __NDS32_REG_ITB__ }; +/* The cctl subtype for intrinsic. */ +enum nds32_cctl_valck +{ + __NDS32_CCTL_L1D_VA_FILLCK__, + __NDS32_CCTL_L1D_VA_ULCK__, + __NDS32_CCTL_L1I_VA_FILLCK__, + __NDS32_CCTL_L1I_VA_ULCK__ +}; + +enum nds32_cctl_idxwbinv +{ + __NDS32_CCTL_L1D_IX_WBINVAL__, + __NDS32_CCTL_L1D_IX_INVAL__, + __NDS32_CCTL_L1D_IX_WB__, + __NDS32_CCTL_L1I_IX_INVAL__ +}; + +enum nds32_cctl_vawbinv +{ + __NDS32_CCTL_L1D_VA_INVAL__, + __NDS32_CCTL_L1D_VA_WB__, + __NDS32_CCTL_L1D_VA_WBINVAL__, + __NDS32_CCTL_L1I_VA_INVAL__ +}; + +enum nds32_cctl_idxread +{ + __NDS32_CCTL_L1D_IX_RTAG__, + __NDS32_CCTL_L1D_IX_RWD__, + __NDS32_CCTL_L1I_IX_RTAG__, + __NDS32_CCTL_L1I_IX_RWD__ +}; + +enum nds32_cctl_idxwrite +{ + __NDS32_CCTL_L1D_IX_WTAG__, + __NDS32_CCTL_L1D_IX_WWD__, + __NDS32_CCTL_L1I_IX_WTAG__, + __NDS32_CCTL_L1I_IX_WWD__ +}; /* ------------------------------------------------------------------------ */ @@ -345,6 +385,51 @@ enum nds32_intrinsic_registers #define NDS32_USR_IFC_LP __NDS32_REG_IFC_LP__ #define NDS32_USR_ITB __NDS32_REG_ITB__ +#define NDS32_CCTL_L1D_VA_FILLCK __NDS32_CCTL_L1D_VA_FILLCK__ +#define NDS32_CCTL_L1D_VA_ULCK __NDS32_CCTL_L1D_VA_ULCK__ +#define NDS32_CCTL_L1I_VA_FILLCK __NDS32_CCTL_L1I_VA_FILLCK__ +#define NDS32_CCTL_L1I_VA_ULCK __NDS32_CCTL_L1I_VA_ULCK__ + +#define NDS32_CCTL_L1D_IX_WBINVAL __NDS32_CCTL_L1D_IX_WBINVAL__ +#define NDS32_CCTL_L1D_IX_INVAL __NDS32_CCTL_L1D_IX_INVAL__ +#define NDS32_CCTL_L1D_IX_WB __NDS32_CCTL_L1D_IX_WB__ +#define NDS32_CCTL_L1I_IX_INVAL __NDS32_CCTL_L1I_IX_INVAL__ + +#define NDS32_CCTL_L1D_VA_INVAL __NDS32_CCTL_L1D_VA_INVAL__ +#define NDS32_CCTL_L1D_VA_WB __NDS32_CCTL_L1D_VA_WB__ +#define NDS32_CCTL_L1D_VA_WBINVAL __NDS32_CCTL_L1D_VA_WBINVAL__ +#define NDS32_CCTL_L1I_VA_INVAL __NDS32_CCTL_L1I_VA_INVAL__ + +#define NDS32_CCTL_L1D_IX_RTAG __NDS32_CCTL_L1D_IX_RTAG__ +#define NDS32_CCTL_L1D_IX_RWD __NDS32_CCTL_L1D_IX_RWD__ +#define NDS32_CCTL_L1I_IX_RTAG __NDS32_CCTL_L1I_IX_RTAG__ +#define NDS32_CCTL_L1I_IX_RWD __NDS32_CCTL_L1I_IX_RWD__ + +#define NDS32_CCTL_L1D_IX_WTAG __NDS32_CCTL_L1D_IX_WTAG__ +#define NDS32_CCTL_L1D_IX_WWD __NDS32_CCTL_L1D_IX_WWD__ +#define NDS32_CCTL_L1I_IX_WTAG __NDS32_CCTL_L1I_IX_WTAG__ +#define NDS32_CCTL_L1I_IX_WWD __NDS32_CCTL_L1I_IX_WWD__ +/* ------------------------------------------------------------------------ */ + +#define __nds32__cctlva_lck(subtype, va) \ + (__builtin_nds32_cctl_va_lck ((subtype), (va))) +#define __nds32__cctlidx_wbinval(subtype, idx) \ + (__builtin_nds32_cctl_idx_wbinval ((subtype), (idx))) +#define __nds32__cctlva_wbinval_alvl(subtype, va) \ + (__builtin_nds32_cctl_va_wbinval_la ((subtype), (va))) +#define __nds32__cctlva_wbinval_one_lvl(subtype, va) \ + (__builtin_nds32_cctl_va_wbinval_l1 ((subtype), (va))) +#define __nds32__cctlidx_read(subtype, idx) \ + (__builtin_nds32_cctl_idx_read ((subtype), (idx))) +#define __nds32__cctlidx_write(subtype, b, idxw) \ + (__builtin_nds32_cctl_idx_write ((subtype), (b), (idxw))) +#define __nds32__cctl_l1d_invalall() \ + (__builtin_nds32_cctl_l1d_invalall()) +#define __nds32__cctl_l1d_wball_alvl() \ + (__builtin_nds32_cctl_l1d_wball_alvl()) +#define __nds32__cctl_l1d_wball_one_lvl() \ + (__builtin_nds32_cctl_l1d_wball_one_lvl()) + #define __nds32__fcpynsd(a, b) \ (__builtin_nds32_fcpynsd ((a), (b))) #define __nds32__fcpynss(a, b) \ diff --git a/gcc/config/nds32/pipelines.md b/gcc/config/nds32/pipelines.md index 52b0e094077..e60b4b7e634 100644 --- a/gcc/config/nds32/pipelines.md +++ b/gcc/config/nds32/pipelines.md @@ -23,7 +23,7 @@ (define_cpu_unit "general_unit" "nds32_machine") (define_insn_reservation "simple_insn" 1 - (eq_attr "type" "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,misc") + (eq_attr "type" "unknown,load,store,load_multiple,store_multiple,alu,alu_shift,mul,mac,div,branch,mmu,misc") "general_unit") ;; ------------------------------------------------------------------------ -- 2.30.2