1 /* GCC backend definitions for the TI MSP430 Processor 2 Copyright (C) 2012-2018 Free Software Foundation, Inc. 3 Contributed by Red Hat. 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 /* Run-time Target Specification */ 23 24 /* True if the MSP430x extensions are enabled. */ 25 #ifndef IN_LIBGCC2 26 extern bool msp430x; 27 #endif 28 29 #define TARGET_CPU_CPP_BUILTINS() \ 30 do \ 31 { \ 32 builtin_define ("NO_TRAMPOLINES"); \ 33 builtin_define ("__MSP430__"); \ 34 builtin_define (msp430_mcu_name ()); \ 35 if (msp430x) \ 36 { \ 37 builtin_define ("__MSP430X__"); \ 38 builtin_assert ("cpu=MSP430X"); \ 39 if (TARGET_LARGE) \ 40 builtin_define ("__MSP430X_LARGE__"); \ 41 } \ 42 else \ 43 builtin_assert ("cpu=MSP430"); \ 44 } \ 45 while (0) 46 47 #undef STARTFILE_SPEC 48 #define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{minrt:crt0-minrt.o%s}%{!minrt:crt0.o%s}} %{!minrt:crtbegin.o%s}" 49 50 /* -lgcc is included because crtend.o needs __mspabi_func_epilog_1. */ 51 #undef ENDFILE_SPEC 52 #define ENDFILE_SPEC "%{!minrt:crtend.o%s} %{minrt:crtn-minrt.o%s}%{!minrt:crtn.o%s} -lgcc" 53 54 #define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \ 55 "%{mcpu=*:-mcpu=%*}%{!mcpu=*:%{mmcu=*:-mmcu=%*}} " /* Pass the CPU type on to the assembler. */ \ 56 "%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \ 57 "%{mlarge:-ml} " /* Tell the assembler if we are building for the LARGE pointer model. */ \ 58 "%{!msim:-md} %{msim:%{mlarge:-md}} " /* Copy data from ROM to RAM if necessary. */ \ 59 "%{msilicon-errata=*:-msilicon-errata=%*} " /* Pass on -msilicon-errata. */ \ 60 "%{msilicon-errata-warn=*:-msilicon-errata-warn=%*} " /* Pass on -msilicon-errata-warn. */ \ 61 "%{ffunction-sections:-gdwarf-sections} " /* If function sections are being created then create DWARF line number sections as well. */ \ 62 "%{mdata-region=*:-mdata-region=%*} " /* Pass on -mdata-region. */ 63 64 /* Enable linker section garbage collection by default, unless we 65 are creating a relocatable binary (gc does not work) or debugging 66 is enabled (the GDB testsuite relies upon unused entities not being deleted). */ 67 #define LINK_SPEC "%{mrelax:--relax} %{mlarge:%{!r:%{!g:--gc-sections}}} " \ 68 "%{mcode-region=*:--code-region=%*} %{mdata-region=*:--data-region=%*}" 69 70 extern const char * msp430_select_hwmult_lib (int, const char **); 71 # define EXTRA_SPEC_FUNCTIONS \ 72 { "msp430_hwmult_lib", msp430_select_hwmult_lib }, 73 74 /* Specify the libraries to include on the linker command line. 75 76 Selecting the hardware multiply library to use is quite complex. 77 If the user has specified -mhwmult=FOO then the mapping is quite 78 easy (and could be handled here in the SPEC string), unless FOO 79 is set to AUTO. In this case the -mmcu= option must be consulted 80 instead. If the -mhwmult= option is not specified then the -mmcu= 81 option must then be examined. If neither -mhwmult= nor -mmcu= are 82 specified then a default hardware multiply library is used. 83 84 Examining the -mmcu=FOO option is difficult, and it is so this 85 reason that a spec function is used. There are so many possible 86 values of FOO that a table is used to look up the name and map 87 it to a hardware multiply library. This table (in device-msp430.c) 88 must be kept in sync with the same table in msp430.c. */ 89 #undef LIB_SPEC 90 #define LIB_SPEC " \ 91 --start-group \ 92 %{mhwmult=auto:%{mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*});:%:msp430_hwmult_lib(default)}; \ 93 mhwmult=*:%:msp430_hwmult_lib(hwmult %{mhwmult=*:%*}); \ 94 mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*}); \ 95 :%:msp430_hwmult_lib(default)} \ 96 -lc \ 97 -lgcc \ 98 -lcrt \ 99 %{msim:-lsim} \ 100 %{!msim:-lnosys} \ 101 --end-group \ 102 %{!T*:%{!msim:%{mmcu=*:--script=%*.ld}}} \ 103 %{!T*:%{msim:%{mlarge:%Tmsp430xl-sim.ld}%{!mlarge:%Tmsp430-sim.ld}}} \ 104 " 105 106 /* Storage Layout */ 107 108 #define BITS_BIG_ENDIAN 0 109 #define BYTES_BIG_ENDIAN 0 110 #define WORDS_BIG_ENDIAN 0 111 112 113 #ifdef IN_LIBGCC2 114 /* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */ 115 #define UNITS_PER_WORD 4 116 /* We have a problem with libgcc2. It only defines two versions of 117 each function, one for "int" and one for "long long". Ie it assumes 118 that "sizeof (int) == sizeof (long)". For the MSP430 this is not true 119 and we need a third set of functions. We explicitly define 120 LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting 121 to get the SI and DI versions from the libgcc2.c sources, and we 122 provide our own set of HI functions, which is why this 123 definition is surrounded by #ifndef..#endif. */ 124 #ifndef LIBGCC2_UNITS_PER_WORD 125 #define LIBGCC2_UNITS_PER_WORD 4 126 #endif 127 #else 128 /* Actual width of a word, in units (bytes). */ 129 #define UNITS_PER_WORD 2 130 #endif 131 132 #define SHORT_TYPE_SIZE 16 133 #define INT_TYPE_SIZE 16 134 #define LONG_TYPE_SIZE 32 135 #define LONG_LONG_TYPE_SIZE 64 136 137 #define FLOAT_TYPE_SIZE 32 138 #define DOUBLE_TYPE_SIZE 64 139 #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/ 140 141 #define DEFAULT_SIGNED_CHAR 0 142 143 #define STRICT_ALIGNMENT 1 144 #define FUNCTION_BOUNDARY 16 145 #define BIGGEST_ALIGNMENT 16 146 #define STACK_BOUNDARY 16 147 #define PARM_BOUNDARY 8 148 #define PCC_BITFIELD_TYPE_MATTERS 1 149 150 #define STACK_GROWS_DOWNWARD 1 151 #define FRAME_GROWS_DOWNWARD 1 152 #define FIRST_PARM_OFFSET(FNDECL) 0 153 154 #define MAX_REGS_PER_ADDRESS 1 155 156 #define Pmode (TARGET_LARGE ? PSImode : HImode) 157 #define POINTER_SIZE (TARGET_LARGE ? 20 : 16) 158 /* This is just for .eh_frame, to match bfd. */ 159 #define PTR_SIZE (TARGET_LARGE ? 4 : 2) 160 #define POINTERS_EXTEND_UNSIGNED 1 161 162 #define ADDR_SPACE_NEAR 1 163 #define ADDR_SPACE_FAR 2 164 165 #define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() 166 167 #if 1 /* XXX */ 168 /* Define this macro if it is advisable to hold scalars in registers 169 in a wider mode than that declared by the program. In such cases, 170 the value is constrained to be within the bounds of the declared 171 type, but kept valid in the wider mode. The signedness of the 172 extension may differ from that of the type. */ 173 174 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ 175 if (GET_MODE_CLASS (MODE) == MODE_INT \ 176 && GET_MODE_SIZE (MODE) < 2) \ 177 (MODE) = HImode; 178 #endif 179 180 /* Layout of Source Language Data Types */ 181 182 #undef SIZE_TYPE 183 #define SIZE_TYPE (TARGET_LARGE ? "__int20 unsigned" : "unsigned int") 184 #undef PTRDIFF_TYPE 185 #define PTRDIFF_TYPE (TARGET_LARGE ? "__int20" : "int") 186 #undef WCHAR_TYPE 187 #define WCHAR_TYPE "long int" 188 #undef WCHAR_TYPE_SIZE 189 #define WCHAR_TYPE_SIZE BITS_PER_WORD 190 #define FUNCTION_MODE HImode 191 #define CASE_VECTOR_MODE Pmode 192 #define HAS_LONG_COND_BRANCH 0 193 #define HAS_LONG_UNCOND_BRANCH 0 194 195 #define LOAD_EXTEND_OP(M) ZERO_EXTEND 196 #define WORD_REGISTER_OPERATIONS 1 197 198 #define MOVE_MAX 8 199 200 #define INCOMING_RETURN_ADDR_RTX \ 201 msp430_incoming_return_addr_rtx () 202 203 #define RETURN_ADDR_RTX(COUNT, FA) \ 204 msp430_return_addr_rtx (COUNT) 205 206 #define SLOW_BYTE_ACCESS 0 207 208 209 /* Register Usage */ 210 211 /* gas doesn't recognize PC (R0), SP (R1), and SR (R2) as register 212 names. */ 213 #define REGISTER_NAMES \ 214 { \ 215 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \ 216 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \ 217 "argptr" \ 218 } 219 220 enum reg_class 221 { 222 NO_REGS, 223 R12_REGS, 224 R13_REGS, 225 GEN_REGS, 226 ALL_REGS, 227 LIM_REG_CLASSES 228 }; 229 230 #define REG_CLASS_NAMES \ 231 { \ 232 "NO_REGS", \ 233 "R12_REGS", \ 234 "R13_REGS", \ 235 "GEN_REGS", \ 236 "ALL_REGS" \ 237 } 238 239 #define REG_CLASS_CONTENTS \ 240 { \ 241 0x00000000, \ 242 0x00001000, \ 243 0x00002000, \ 244 0x0000fff2, \ 245 0x0001ffff \ 246 } 247 248 #define GENERAL_REGS GEN_REGS 249 #define BASE_REG_CLASS GEN_REGS 250 #define INDEX_REG_CLASS GEN_REGS 251 #define N_REG_CLASSES (int) LIM_REG_CLASSES 252 253 #define PC_REGNUM 0 254 #define STACK_POINTER_REGNUM 1 255 #define CC_REGNUM 2 256 #define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */ 257 #define ARG_POINTER_REGNUM 16 258 #define STATIC_CHAIN_REGNUM 5 /* FIXME */ 259 260 #define FIRST_PSEUDO_REGISTER 17 261 262 #define REGNO_REG_CLASS(REGNO) ((REGNO) < 17 \ 263 ? GEN_REGS : NO_REGS) 264 265 #define TRAMPOLINE_SIZE 4 /* FIXME */ 266 #define TRAMPOLINE_ALIGNMENT 16 /* FIXME */ 267 268 #define ELIMINABLE_REGS \ 269 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ 270 { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ 271 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} 272 273 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 274 (OFFSET) = msp430_initial_elimination_offset ((FROM), (TO)) 275 276 277 #define FUNCTION_ARG_REGNO_P(N) ((N) >= 8 && (N) < ARG_POINTER_REGNUM) 278 #define DEFAULT_PCC_STRUCT_RETURN 0 279 280 /* 1 == register can't be used by gcc, in general 281 0 == register can be used by gcc, in general */ 282 #define FIXED_REGISTERS \ 283 { \ 284 1,0,1,1, 0,0,0,0, \ 285 0,0,0,0, 0,0,0,0, \ 286 1, \ 287 } 288 289 /* 1 == value changes across function calls 290 0 == value is the same after a call */ 291 /* R4 through R10 are callee-saved */ 292 #define CALL_USED_REGISTERS \ 293 { \ 294 1,0,1,1, 0,0,0,0, \ 295 0,0,0,1, 1,1,1,1, \ 296 1, \ 297 } 298 299 #define REG_ALLOC_ORDER \ 300 { 12, 13, 14, 15, 10, 9, 8, 7, 6, 5, 4, 11, 0, 1, 2, 3, 16 } 301 /* { 11, 15, 14, 13, 12, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3, 16 }*/ 302 303 #define REGNO_OK_FOR_BASE_P(regno) 1 304 #define REGNO_OK_FOR_INDEX_P(regno) 1 305 306 307 308 typedef struct 309 { 310 /* These two are the current argument status. */ 311 char reg_used[4]; 312 #define CA_FIRST_REG 12 313 char can_split; 314 /* These two are temporaries used internally. */ 315 char start_reg; 316 char reg_count; 317 char mem_count; 318 char special_p; 319 } CUMULATIVE_ARGS; 320 321 #define INIT_CUMULATIVE_ARGS(CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ 322 msp430_init_cumulative_args (&CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) 323 324 325 /* FIXME */ 326 #define NO_PROFILE_COUNTERS 1 327 #define PROFILE_BEFORE_PROLOGUE 1 328 329 #define FUNCTION_PROFILER(FILE, LABELNO) \ 330 fprintf (FILE, "\tcall\t__mcount\n"); 331 332 /* Exception Handling */ 333 334 /* R12,R13,R14 - EH data 335 R15 - stack adjustment */ 336 337 #define EH_RETURN_DATA_REGNO(N) \ 338 (((N) < 3) ? ((N) + 12) : INVALID_REGNUM) 339 340 #define EH_RETURN_HANDLER_RTX \ 341 gen_rtx_MEM(Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG(Pmode, SP_REGNO), gen_rtx_REG (Pmode, 15))) 342 343 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15) 344 345 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4 346 347 348 /* Stack Layout and Calling Conventions */ 349 350 351 /* Addressing Modes */ 352 353 354 355 #define TEXT_SECTION_ASM_OP ".text" 356 #define DATA_SECTION_ASM_OP ".data" 357 #define BSS_SECTION_ASM_OP "\t.section .bss" 358 359 #define ASM_COMMENT_START " ;" 360 #define ASM_APP_ON "" 361 #define ASM_APP_OFF "" 362 #define LOCAL_LABEL_PREFIX ".L" 363 #undef USER_LABEL_PREFIX 364 #define USER_LABEL_PREFIX "" 365 366 #define GLOBAL_ASM_OP "\t.global\t" 367 368 #define ASM_OUTPUT_LABELREF(FILE, SYM) msp430_output_labelref ((FILE), (SYM)) 369 370 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 371 fprintf (FILE, "\t.long .L%d\n", VALUE) 372 373 /* This is how to output an element of a case-vector that is relative. 374 Note: The local label referenced by the "3b" below is emitted by 375 the tablejump insn. */ 376 377 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 378 fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) 379 380 381 #define ASM_OUTPUT_ALIGN(STREAM, LOG) \ 382 do \ 383 { \ 384 if ((LOG) == 0) \ 385 break; \ 386 fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \ 387 } \ 388 while (0) 389 390 #define JUMP_TABLES_IN_TEXT_SECTION 1 391 392 #undef DWARF2_ADDR_SIZE 393 #define DWARF2_ADDR_SIZE 4 394 395 #define INCOMING_FRAME_SP_OFFSET (TARGET_LARGE ? 4 : 2) 396 397 #undef PREFERRED_DEBUGGING_TYPE 398 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG 399 400 #define DWARF2_ASM_LINE_DEBUG_INFO 1 401 402 /* Prevent reload (and others) from choosing HImode stack slots 403 when spilling hard registers when they may contain PSImode values. */ 404 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \ 405 ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode : choose_hard_reg_mode ((REGNO), (NREGS), false)) 406 407 #define ACCUMULATE_OUTGOING_ARGS 1 408 409 #undef ASM_DECLARE_FUNCTION_NAME 410 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ 411 msp430_start_function ((FILE), (NAME), (DECL)) 412 413 #define TARGET_HAS_NO_HW_DIVIDE (! TARGET_HWMULT) 414 415 #undef USE_SELECT_SECTION_FOR_FUNCTIONS 416 #define USE_SELECT_SECTION_FOR_FUNCTIONS 1 417 418 #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) \ 419 msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) 420