1 /* GCC backend definitions for the TI MSP430 Processor 2 Copyright (C) 2012-2019 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 /* TARGET_VTABLE_ENTRY_ALIGN defaults to POINTER_SIZE, which is 20 for 163 TARGET_LARGE. Pointer alignment is always 16 for MSP430, so set explicitly 164 here. */ 165 #define TARGET_VTABLE_ENTRY_ALIGN 16 166 167 #define ADDR_SPACE_NEAR 1 168 #define ADDR_SPACE_FAR 2 169 170 #define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() 171 172 #if 1 /* XXX */ 173 /* Define this macro if it is advisable to hold scalars in registers 174 in a wider mode than that declared by the program. In such cases, 175 the value is constrained to be within the bounds of the declared 176 type, but kept valid in the wider mode. The signedness of the 177 extension may differ from that of the type. */ 178 179 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ 180 if (GET_MODE_CLASS (MODE) == MODE_INT \ 181 && GET_MODE_SIZE (MODE) < 2) \ 182 (MODE) = HImode; 183 #endif 184 185 /* Layout of Source Language Data Types */ 186 187 #undef SIZE_TYPE 188 #define SIZE_TYPE (TARGET_LARGE ? "__int20 unsigned" : "unsigned int") 189 #undef PTRDIFF_TYPE 190 #define PTRDIFF_TYPE (TARGET_LARGE ? "__int20" : "int") 191 #undef WCHAR_TYPE 192 #define WCHAR_TYPE "long int" 193 #undef WCHAR_TYPE_SIZE 194 #define WCHAR_TYPE_SIZE BITS_PER_WORD 195 #define FUNCTION_MODE HImode 196 #define CASE_VECTOR_MODE Pmode 197 #define HAS_LONG_COND_BRANCH 0 198 #define HAS_LONG_UNCOND_BRANCH 0 199 200 #define LOAD_EXTEND_OP(M) ZERO_EXTEND 201 #define WORD_REGISTER_OPERATIONS 1 202 203 #define MOVE_MAX 8 204 205 #define INCOMING_RETURN_ADDR_RTX \ 206 msp430_incoming_return_addr_rtx () 207 208 #define RETURN_ADDR_RTX(COUNT, FA) \ 209 msp430_return_addr_rtx (COUNT) 210 211 #define SLOW_BYTE_ACCESS 0 212 213 214 /* Register Usage */ 215 216 /* gas doesn't recognize PC (R0), SP (R1), and SR (R2) as register 217 names. */ 218 #define REGISTER_NAMES \ 219 { \ 220 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \ 221 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \ 222 "argptr" \ 223 } 224 225 enum reg_class 226 { 227 NO_REGS, 228 R12_REGS, 229 R13_REGS, 230 GEN_REGS, 231 ALL_REGS, 232 LIM_REG_CLASSES 233 }; 234 235 #define REG_CLASS_NAMES \ 236 { \ 237 "NO_REGS", \ 238 "R12_REGS", \ 239 "R13_REGS", \ 240 "GEN_REGS", \ 241 "ALL_REGS" \ 242 } 243 244 #define REG_CLASS_CONTENTS \ 245 { \ 246 0x00000000, \ 247 0x00001000, \ 248 0x00002000, \ 249 0x0000fff3, \ 250 0x0001ffff \ 251 } 252 253 /* GENERAL_REGS just means that the "g" and "r" constraints can use these 254 registers. 255 Even though R0 (PC) and R1 (SP) are not "general" in that they can be used 256 for any purpose by the register allocator, they are general in that they can 257 be used by any instruction in any addressing mode. */ 258 #define GENERAL_REGS GEN_REGS 259 #define BASE_REG_CLASS GEN_REGS 260 #define INDEX_REG_CLASS GEN_REGS 261 #define N_REG_CLASSES (int) LIM_REG_CLASSES 262 263 #define PC_REGNUM 0 264 #define STACK_POINTER_REGNUM 1 265 #define CC_REGNUM 2 266 #define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */ 267 #define ARG_POINTER_REGNUM 16 268 #define STATIC_CHAIN_REGNUM 5 /* FIXME */ 269 270 #define FIRST_PSEUDO_REGISTER 17 271 272 #define REGNO_REG_CLASS(REGNO) (REGNO != 2 \ 273 && REGNO != 3 \ 274 && REGNO < 17 \ 275 ? GEN_REGS : NO_REGS) 276 277 #define TRAMPOLINE_SIZE 4 /* FIXME */ 278 #define TRAMPOLINE_ALIGNMENT 16 /* FIXME */ 279 280 #define ELIMINABLE_REGS \ 281 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ 282 { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ 283 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} 284 285 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 286 (OFFSET) = msp430_initial_elimination_offset ((FROM), (TO)) 287 288 289 #define FUNCTION_ARG_REGNO_P(N) ((N) >= 8 && (N) < ARG_POINTER_REGNUM) 290 #define DEFAULT_PCC_STRUCT_RETURN 0 291 292 /* 1 == register can't be used by gcc, in general 293 0 == register can be used by gcc, in general */ 294 #define FIXED_REGISTERS \ 295 { \ 296 1,0,1,1, 0,0,0,0, \ 297 0,0,0,0, 0,0,0,0, \ 298 1, \ 299 } 300 301 /* 1 == value changes across function calls 302 0 == value is the same after a call */ 303 /* R4 through R10 are callee-saved */ 304 #define CALL_USED_REGISTERS \ 305 { \ 306 1,0,1,1, 0,0,0,0, \ 307 0,0,0,1, 1,1,1,1, \ 308 1, \ 309 } 310 311 #define REG_ALLOC_ORDER \ 312 { 12, 13, 14, 15, 10, 9, 8, 7, 6, 5, 4, 11, 0, 1, 2, 3, 16 } 313 /* { 11, 15, 14, 13, 12, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3, 16 }*/ 314 315 #define REGNO_OK_FOR_BASE_P(regno) 1 316 #define REGNO_OK_FOR_INDEX_P(regno) 1 317 318 319 320 typedef struct 321 { 322 /* These two are the current argument status. */ 323 char reg_used[4]; 324 #define CA_FIRST_REG 12 325 char can_split; 326 /* These two are temporaries used internally. */ 327 char start_reg; 328 char reg_count; 329 char mem_count; 330 char special_p; 331 } CUMULATIVE_ARGS; 332 333 #define INIT_CUMULATIVE_ARGS(CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ 334 msp430_init_cumulative_args (&CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) 335 336 337 /* FIXME */ 338 #define NO_PROFILE_COUNTERS 1 339 #define PROFILE_BEFORE_PROLOGUE 1 340 341 #define FUNCTION_PROFILER(FILE, LABELNO) \ 342 fprintf (FILE, "\tcall\t__mcount\n"); 343 344 /* Exception Handling */ 345 346 /* R12,R13,R14 - EH data 347 R15 - stack adjustment */ 348 349 #define EH_RETURN_DATA_REGNO(N) \ 350 (((N) < 3) ? ((N) + 12) : INVALID_REGNUM) 351 352 #define EH_RETURN_HANDLER_RTX \ 353 gen_rtx_MEM(Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG(Pmode, SP_REGNO), gen_rtx_REG (Pmode, 15))) 354 355 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15) 356 357 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4 358 359 360 /* Stack Layout and Calling Conventions */ 361 362 363 /* Addressing Modes */ 364 365 366 367 #define TEXT_SECTION_ASM_OP ".text" 368 #define DATA_SECTION_ASM_OP ".data" 369 #define BSS_SECTION_ASM_OP "\t.section .bss" 370 371 #define ASM_COMMENT_START " ;" 372 #define ASM_APP_ON "" 373 #define ASM_APP_OFF "" 374 #define LOCAL_LABEL_PREFIX ".L" 375 #undef USER_LABEL_PREFIX 376 #define USER_LABEL_PREFIX "" 377 378 #define GLOBAL_ASM_OP "\t.global\t" 379 380 #define ASM_OUTPUT_LABELREF(FILE, SYM) msp430_output_labelref ((FILE), (SYM)) 381 382 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 383 fprintf (FILE, "\t.long .L%d\n", VALUE) 384 385 /* This is how to output an element of a case-vector that is relative. 386 Note: The local label referenced by the "3b" below is emitted by 387 the tablejump insn. */ 388 389 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 390 fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) 391 392 393 #define ASM_OUTPUT_ALIGN(STREAM, LOG) \ 394 do \ 395 { \ 396 if ((LOG) == 0) \ 397 break; \ 398 fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \ 399 } \ 400 while (0) 401 402 #define JUMP_TABLES_IN_TEXT_SECTION 1 403 404 #undef DWARF2_ADDR_SIZE 405 #define DWARF2_ADDR_SIZE 4 406 407 #define INCOMING_FRAME_SP_OFFSET (TARGET_LARGE ? 4 : 2) 408 409 #undef PREFERRED_DEBUGGING_TYPE 410 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG 411 412 #define DWARF2_ASM_LINE_DEBUG_INFO 1 413 414 /* Prevent reload (and others) from choosing HImode stack slots 415 when spilling hard registers when they may contain PSImode values. */ 416 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \ 417 ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode : choose_hard_reg_mode ((REGNO), (NREGS), false)) 418 419 #define ACCUMULATE_OUTGOING_ARGS 1 420 421 #undef ASM_DECLARE_FUNCTION_NAME 422 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ 423 msp430_start_function ((FILE), (NAME), (DECL)) 424 425 #define TARGET_HAS_NO_HW_DIVIDE (! TARGET_HWMULT) 426 427 #undef USE_SELECT_SECTION_FOR_FUNCTIONS 428 #define USE_SELECT_SECTION_FOR_FUNCTIONS 1 429 430 #define ASM_OUTPUT_ALIGNED_DECL_COMMON(FILE, DECL, NAME, SIZE, ALIGN) \ 431 msp430_output_aligned_decl_common ((FILE), (DECL), (NAME), (SIZE), (ALIGN)) 432