nds32-intrinsic.c revision 1.1
1/* Intrinsic functions of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2015 Free Software Foundation, Inc. 3 Contributed by Andes Technology Corporation. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published 9 by the Free Software Foundation; either version 3, or (at your 10 option) any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21/* ------------------------------------------------------------------------ */ 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "tm.h" 27#include "hash-set.h" 28#include "machmode.h" 29#include "vec.h" 30#include "double-int.h" 31#include "input.h" 32#include "alias.h" 33#include "symtab.h" 34#include "wide-int.h" 35#include "inchash.h" 36#include "tree.h" 37#include "stor-layout.h" 38#include "varasm.h" 39#include "calls.h" 40#include "rtl.h" 41#include "regs.h" 42#include "hard-reg-set.h" 43#include "insn-config.h" /* Required by recog.h. */ 44#include "conditions.h" 45#include "output.h" 46#include "insn-attr.h" /* For DFA state_t. */ 47#include "insn-codes.h" /* For CODE_FOR_xxx. */ 48#include "reload.h" /* For push_reload(). */ 49#include "flags.h" 50#include "function.h" 51#include "hashtab.h" 52#include "statistics.h" 53#include "real.h" 54#include "fixed-value.h" 55#include "insn-config.h" 56#include "expmed.h" 57#include "dojump.h" 58#include "explow.h" 59#include "emit-rtl.h" 60#include "stmt.h" 61#include "expr.h" 62#include "recog.h" 63#include "diagnostic-core.h" 64#include "dominance.h" 65#include "cfg.h" 66#include "cfgrtl.h" 67#include "cfganal.h" 68#include "lcm.h" 69#include "cfgbuild.h" 70#include "cfgcleanup.h" 71#include "predict.h" 72#include "basic-block.h" 73#include "df.h" 74#include "tm_p.h" 75#include "tm-constrs.h" 76#include "optabs.h" /* For GEN_FCN. */ 77#include "target.h" 78#include "target-def.h" 79#include "langhooks.h" /* For add_builtin_function(). */ 80#include "ggc.h" 81#include "builtins.h" 82 83/* ------------------------------------------------------------------------ */ 84 85/* Function to expand builtin function for 86 '[(unspec_volatile [(reg)])]'. */ 87static rtx 88nds32_expand_builtin_null_ftype_reg (enum insn_code icode, 89 tree exp, rtx target) 90{ 91 /* Mapping: 92 ops[0] <--> value0 <--> arg0 */ 93 struct expand_operand ops[1]; 94 tree arg0; 95 rtx value0; 96 97 /* Grab the incoming arguments and extract its rtx. */ 98 arg0 = CALL_EXPR_ARG (exp, 0); 99 value0 = expand_normal (arg0); 100 101 /* Create operands. */ 102 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); 103 104 /* Emit new instruction. */ 105 if (!maybe_expand_insn (icode, 1, ops)) 106 error ("invalid argument to built-in function"); 107 108 return target; 109} 110 111/* Function to expand builtin function for 112 '[(set (reg) (unspec_volatile [(imm)]))]'. */ 113static rtx 114nds32_expand_builtin_reg_ftype_imm (enum insn_code icode, 115 tree exp, rtx target) 116{ 117 /* Mapping: 118 ops[0] <--> target <--> exp 119 ops[1] <--> value0 <--> arg0 */ 120 struct expand_operand ops[2]; 121 tree arg0; 122 rtx value0; 123 124 /* Grab the incoming arguments and extract its rtx. */ 125 arg0 = CALL_EXPR_ARG (exp, 0); 126 value0 = expand_normal (arg0); 127 128 /* Create operands. */ 129 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp))); 130 create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0))); 131 132 /* Emit new instruction. */ 133 if (!maybe_expand_insn (icode, 2, ops)) 134 error ("invalid argument to built-in function"); 135 136 return target; 137} 138 139/* Function to expand builtin function for 140 '[(unspec_volatile [(reg) (imm)])]' pattern. */ 141static rtx 142nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode, 143 tree exp, rtx target) 144{ 145 /* Mapping: 146 ops[0] <--> value0 <--> arg0 147 ops[1] <--> value1 <--> arg1 */ 148 struct expand_operand ops[2]; 149 tree arg0, arg1; 150 rtx value0, value1; 151 152 /* Grab the incoming arguments and extract its rtx. */ 153 arg0 = CALL_EXPR_ARG (exp, 0); 154 arg1 = CALL_EXPR_ARG (exp, 1); 155 value0 = expand_normal (arg0); 156 value1 = expand_normal (arg1); 157 158 /* Create operands. */ 159 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); 160 create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1))); 161 162 /* Emit new instruction. */ 163 if (!maybe_expand_insn (icode, 2, ops)) 164 error ("invalid argument to built-in function"); 165 166 return target; 167} 168 169/* ------------------------------------------------------------------------ */ 170 171void 172nds32_init_builtins_impl (void) 173{ 174 tree pointer_type_node = build_pointer_type (integer_type_node); 175 176 tree void_ftype_void = build_function_type (void_type_node, 177 void_list_node); 178 179 tree void_ftype_pint = build_function_type_list (void_type_node, 180 pointer_type_node, 181 NULL_TREE); 182 183 tree int_ftype_int = build_function_type_list (integer_type_node, 184 integer_type_node, 185 NULL_TREE); 186 187 tree void_ftype_int_int = build_function_type_list (void_type_node, 188 integer_type_node, 189 integer_type_node, 190 NULL_TREE); 191 192 /* Cache. */ 193 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint, 194 NDS32_BUILTIN_ISYNC, 195 BUILT_IN_MD, NULL, NULL_TREE); 196 add_builtin_function ("__builtin_nds32_isb", void_ftype_void, 197 NDS32_BUILTIN_ISB, 198 BUILT_IN_MD, NULL, NULL_TREE); 199 200 /* Register Transfer. */ 201 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int, 202 NDS32_BUILTIN_MFSR, 203 BUILT_IN_MD, NULL, NULL_TREE); 204 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int, 205 NDS32_BUILTIN_MFUSR, 206 BUILT_IN_MD, NULL, NULL_TREE); 207 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int, 208 NDS32_BUILTIN_MTSR, 209 BUILT_IN_MD, NULL, NULL_TREE); 210 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int, 211 NDS32_BUILTIN_MTUSR, 212 BUILT_IN_MD, NULL, NULL_TREE); 213 214 /* Interrupt. */ 215 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void, 216 NDS32_BUILTIN_SETGIE_EN, 217 BUILT_IN_MD, NULL, NULL_TREE); 218 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void, 219 NDS32_BUILTIN_SETGIE_DIS, 220 BUILT_IN_MD, NULL, NULL_TREE); 221} 222 223 224rtx 225nds32_expand_builtin_impl (tree exp, 226 rtx target, 227 rtx subtarget ATTRIBUTE_UNUSED, 228 machine_mode mode ATTRIBUTE_UNUSED, 229 int ignore ATTRIBUTE_UNUSED) 230{ 231 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 232 233 int fcode = DECL_FUNCTION_CODE (fndecl); 234 235 switch (fcode) 236 { 237 /* Cache. */ 238 case NDS32_BUILTIN_ISYNC: 239 return nds32_expand_builtin_null_ftype_reg 240 (CODE_FOR_unspec_volatile_isync, exp, target); 241 case NDS32_BUILTIN_ISB: 242 /* Since there are no result and operands for isb instruciton, 243 we can simply emit this rtx. */ 244 emit_insn (gen_unspec_volatile_isb ()); 245 return target; 246 247 /* Register Transfer. */ 248 case NDS32_BUILTIN_MFSR: 249 return nds32_expand_builtin_reg_ftype_imm 250 (CODE_FOR_unspec_volatile_mfsr, exp, target); 251 case NDS32_BUILTIN_MFUSR: 252 return nds32_expand_builtin_reg_ftype_imm 253 (CODE_FOR_unspec_volatile_mfusr, exp, target); 254 case NDS32_BUILTIN_MTSR: 255 return nds32_expand_builtin_null_ftype_reg_imm 256 (CODE_FOR_unspec_volatile_mtsr, exp, target); 257 case NDS32_BUILTIN_MTUSR: 258 return nds32_expand_builtin_null_ftype_reg_imm 259 (CODE_FOR_unspec_volatile_mtusr, exp, target); 260 261 /* Interrupt. */ 262 case NDS32_BUILTIN_SETGIE_EN: 263 /* Since there are no result and operands for setgie.e instruciton, 264 we can simply emit this rtx. */ 265 emit_insn (gen_unspec_volatile_setgie_en ()); 266 return target; 267 case NDS32_BUILTIN_SETGIE_DIS: 268 /* Since there are no result and operands for setgie.d instruciton, 269 we can simply emit this rtx. */ 270 emit_insn (gen_unspec_volatile_setgie_dis ()); 271 return target; 272 273 default: 274 gcc_unreachable (); 275 } 276 277 return NULL_RTX; 278} 279 280/* ------------------------------------------------------------------------ */ 281