nds32-intrinsic.c revision 1.1.1.2
1/* Intrinsic functions of Andes NDS32 cpu for GNU compiler 2 Copyright (C) 2012-2016 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 "backend.h" 27#include "target.h" 28#include "rtl.h" 29#include "tree.h" 30#include "optabs.h" /* For GEN_FCN. */ 31#include "diagnostic-core.h" 32#include "stor-layout.h" 33#include "expr.h" 34#include "langhooks.h" /* For add_builtin_function(). */ 35 36/* ------------------------------------------------------------------------ */ 37 38/* Function to expand builtin function for 39 '[(unspec_volatile [(reg)])]'. */ 40static rtx 41nds32_expand_builtin_null_ftype_reg (enum insn_code icode, 42 tree exp, rtx target) 43{ 44 /* Mapping: 45 ops[0] <--> value0 <--> arg0 */ 46 struct expand_operand ops[1]; 47 tree arg0; 48 rtx value0; 49 50 /* Grab the incoming arguments and extract its rtx. */ 51 arg0 = CALL_EXPR_ARG (exp, 0); 52 value0 = expand_normal (arg0); 53 54 /* Create operands. */ 55 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); 56 57 /* Emit new instruction. */ 58 if (!maybe_expand_insn (icode, 1, ops)) 59 error ("invalid argument to built-in function"); 60 61 return target; 62} 63 64/* Function to expand builtin function for 65 '[(set (reg) (unspec_volatile [(imm)]))]'. */ 66static rtx 67nds32_expand_builtin_reg_ftype_imm (enum insn_code icode, 68 tree exp, rtx target) 69{ 70 /* Mapping: 71 ops[0] <--> target <--> exp 72 ops[1] <--> value0 <--> arg0 */ 73 struct expand_operand ops[2]; 74 tree arg0; 75 rtx value0; 76 77 /* Grab the incoming arguments and extract its rtx. */ 78 arg0 = CALL_EXPR_ARG (exp, 0); 79 value0 = expand_normal (arg0); 80 81 /* Create operands. */ 82 create_output_operand (&ops[0], target, TYPE_MODE (TREE_TYPE (exp))); 83 create_input_operand (&ops[1], value0, TYPE_MODE (TREE_TYPE (arg0))); 84 85 /* Emit new instruction. */ 86 if (!maybe_expand_insn (icode, 2, ops)) 87 error ("invalid argument to built-in function"); 88 89 return target; 90} 91 92/* Function to expand builtin function for 93 '[(unspec_volatile [(reg) (imm)])]' pattern. */ 94static rtx 95nds32_expand_builtin_null_ftype_reg_imm (enum insn_code icode, 96 tree exp, rtx target) 97{ 98 /* Mapping: 99 ops[0] <--> value0 <--> arg0 100 ops[1] <--> value1 <--> arg1 */ 101 struct expand_operand ops[2]; 102 tree arg0, arg1; 103 rtx value0, value1; 104 105 /* Grab the incoming arguments and extract its rtx. */ 106 arg0 = CALL_EXPR_ARG (exp, 0); 107 arg1 = CALL_EXPR_ARG (exp, 1); 108 value0 = expand_normal (arg0); 109 value1 = expand_normal (arg1); 110 111 /* Create operands. */ 112 create_input_operand (&ops[0], value0, TYPE_MODE (TREE_TYPE (arg0))); 113 create_input_operand (&ops[1], value1, TYPE_MODE (TREE_TYPE (arg1))); 114 115 /* Emit new instruction. */ 116 if (!maybe_expand_insn (icode, 2, ops)) 117 error ("invalid argument to built-in function"); 118 119 return target; 120} 121 122/* ------------------------------------------------------------------------ */ 123 124void 125nds32_init_builtins_impl (void) 126{ 127 tree pointer_type_node = build_pointer_type (integer_type_node); 128 129 tree void_ftype_void = build_function_type (void_type_node, 130 void_list_node); 131 132 tree void_ftype_pint = build_function_type_list (void_type_node, 133 pointer_type_node, 134 NULL_TREE); 135 136 tree int_ftype_int = build_function_type_list (integer_type_node, 137 integer_type_node, 138 NULL_TREE); 139 140 tree void_ftype_int_int = build_function_type_list (void_type_node, 141 integer_type_node, 142 integer_type_node, 143 NULL_TREE); 144 145 /* Cache. */ 146 add_builtin_function ("__builtin_nds32_isync", void_ftype_pint, 147 NDS32_BUILTIN_ISYNC, 148 BUILT_IN_MD, NULL, NULL_TREE); 149 add_builtin_function ("__builtin_nds32_isb", void_ftype_void, 150 NDS32_BUILTIN_ISB, 151 BUILT_IN_MD, NULL, NULL_TREE); 152 153 /* Register Transfer. */ 154 add_builtin_function ("__builtin_nds32_mfsr", int_ftype_int, 155 NDS32_BUILTIN_MFSR, 156 BUILT_IN_MD, NULL, NULL_TREE); 157 add_builtin_function ("__builtin_nds32_mfusr", int_ftype_int, 158 NDS32_BUILTIN_MFUSR, 159 BUILT_IN_MD, NULL, NULL_TREE); 160 add_builtin_function ("__builtin_nds32_mtsr", void_ftype_int_int, 161 NDS32_BUILTIN_MTSR, 162 BUILT_IN_MD, NULL, NULL_TREE); 163 add_builtin_function ("__builtin_nds32_mtusr", void_ftype_int_int, 164 NDS32_BUILTIN_MTUSR, 165 BUILT_IN_MD, NULL, NULL_TREE); 166 167 /* Interrupt. */ 168 add_builtin_function ("__builtin_nds32_setgie_en", void_ftype_void, 169 NDS32_BUILTIN_SETGIE_EN, 170 BUILT_IN_MD, NULL, NULL_TREE); 171 add_builtin_function ("__builtin_nds32_setgie_dis", void_ftype_void, 172 NDS32_BUILTIN_SETGIE_DIS, 173 BUILT_IN_MD, NULL, NULL_TREE); 174} 175 176 177rtx 178nds32_expand_builtin_impl (tree exp, 179 rtx target, 180 rtx subtarget ATTRIBUTE_UNUSED, 181 machine_mode mode ATTRIBUTE_UNUSED, 182 int ignore ATTRIBUTE_UNUSED) 183{ 184 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 185 186 int fcode = DECL_FUNCTION_CODE (fndecl); 187 188 switch (fcode) 189 { 190 /* Cache. */ 191 case NDS32_BUILTIN_ISYNC: 192 return nds32_expand_builtin_null_ftype_reg 193 (CODE_FOR_unspec_volatile_isync, exp, target); 194 case NDS32_BUILTIN_ISB: 195 /* Since there are no result and operands for isb instruciton, 196 we can simply emit this rtx. */ 197 emit_insn (gen_unspec_volatile_isb ()); 198 return target; 199 200 /* Register Transfer. */ 201 case NDS32_BUILTIN_MFSR: 202 return nds32_expand_builtin_reg_ftype_imm 203 (CODE_FOR_unspec_volatile_mfsr, exp, target); 204 case NDS32_BUILTIN_MFUSR: 205 return nds32_expand_builtin_reg_ftype_imm 206 (CODE_FOR_unspec_volatile_mfusr, exp, target); 207 case NDS32_BUILTIN_MTSR: 208 return nds32_expand_builtin_null_ftype_reg_imm 209 (CODE_FOR_unspec_volatile_mtsr, exp, target); 210 case NDS32_BUILTIN_MTUSR: 211 return nds32_expand_builtin_null_ftype_reg_imm 212 (CODE_FOR_unspec_volatile_mtusr, exp, target); 213 214 /* Interrupt. */ 215 case NDS32_BUILTIN_SETGIE_EN: 216 /* Since there are no result and operands for setgie.e instruciton, 217 we can simply emit this rtx. */ 218 emit_insn (gen_unspec_volatile_setgie_en ()); 219 return target; 220 case NDS32_BUILTIN_SETGIE_DIS: 221 /* Since there are no result and operands for setgie.d instruciton, 222 we can simply emit this rtx. */ 223 emit_insn (gen_unspec_volatile_setgie_dis ()); 224 return target; 225 226 default: 227 gcc_unreachable (); 228 } 229 230 return NULL_RTX; 231} 232 233/* ------------------------------------------------------------------------ */ 234