1 /* GCC backend definitions for the TI MSP430 Processor 2 Copyright (C) 2012-2014 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 "%{ffunction-sections:-gdwarf-sections} " /* If function sections are being created then create DWARF line number sections as well. */ 60 61 /* Enable linker section garbage collection by default, unless we 62 are creating a relocatable binary (gc does not work) or debugging 63 is enabled (the GDB testsuite relies upon unused entities not being deleted). */ 64 #define LINK_SPEC "%{mrelax:--relax} %{mlarge:%{!r:%{!g:--gc-sections}}}" 65 66 #undef LIB_SPEC 67 #define LIB_SPEC " \ 68 --start-group \ 69 -lc \ 70 -lgcc \ 71 -lcrt \ 72 %{msim:-lsim} \ 73 %{!msim:-lnosys} \ 74 --end-group \ 75 %{!T*:%{!msim:%{mmcu=*:--script=%*.ld}}} \ 76 %{!T*:%{!msim:%{!mmcu=*:%Tmsp430.ld}}} \ 77 %{!T*:%{msim:%{mlarge:%Tmsp430xl-sim.ld}%{!mlarge:%Tmsp430-sim.ld}}} \ 78 " 79 80 /* Storage Layout */ 81 82 #define BITS_BIG_ENDIAN 0 83 #define BYTES_BIG_ENDIAN 0 84 #define WORDS_BIG_ENDIAN 0 85 86 87 #ifdef IN_LIBGCC2 88 /* This is to get correct SI and DI modes in libgcc2.c (32 and 64 bits). */ 89 #define UNITS_PER_WORD 4 90 /* We have a problem with libgcc2. It only defines two versions of 91 each function, one for "int" and one for "long long". Ie it assumes 92 that "sizeof (int) == sizeof (long)". For the MSP430 this is not true 93 and we need a third set of functions. We explicitly define 94 LIBGCC2_UNITS_PER_WORD here so that it is clear that we are expecting 95 to get the SI and DI versions from the libgcc2.c sources, and we 96 provide our own set of HI functions, which is why this 97 definition is surrounded by #ifndef..#endif. */ 98 #ifndef LIBGCC2_UNITS_PER_WORD 99 #define LIBGCC2_UNITS_PER_WORD 4 100 #endif 101 #else 102 /* Actual width of a word, in units (bytes). */ 103 #define UNITS_PER_WORD 2 104 #endif 105 106 #define SHORT_TYPE_SIZE 16 107 #define INT_TYPE_SIZE 16 108 #define LONG_TYPE_SIZE 32 109 #define LONG_LONG_TYPE_SIZE 64 110 111 #define FLOAT_TYPE_SIZE 32 112 #define DOUBLE_TYPE_SIZE 64 113 #define LONG_DOUBLE_TYPE_SIZE 64 /*DOUBLE_TYPE_SIZE*/ 114 115 #define LIBGCC2_HAS_DF_MODE 1 116 #define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 117 118 #define DEFAULT_SIGNED_CHAR 0 119 120 #define STRICT_ALIGNMENT 1 121 #define FUNCTION_BOUNDARY 16 122 #define BIGGEST_ALIGNMENT 16 123 #define STACK_BOUNDARY 16 124 #define PARM_BOUNDARY 8 125 #define PCC_BITFIELD_TYPE_MATTERS 1 126 127 #define STACK_GROWS_DOWNWARD 1 128 #define FRAME_GROWS_DOWNWARD 1 129 #define FIRST_PARM_OFFSET(FNDECL) 0 130 131 #define MAX_REGS_PER_ADDRESS 1 132 133 #define Pmode (TARGET_LARGE ? PSImode : HImode) 134 /* Note: 32 is a lie. Large pointers are actually 20-bits wide. But gcc 135 thinks that any non-power-of-2 pointer size equates to BLKmode, which 136 causes all kinds of problems... */ 137 #define POINTER_SIZE (TARGET_LARGE ? 32 : 16) 138 #define POINTERS_EXTEND_UNSIGNED 1 139 140 #define ADDR_SPACE_NEAR 1 141 #define ADDR_SPACE_FAR 2 142 143 #define REGISTER_TARGET_PRAGMAS() msp430_register_pragmas() 144 145 #if 1 /* XXX */ 146 /* Define this macro if it is advisable to hold scalars in registers 147 in a wider mode than that declared by the program. In such cases, 148 the value is constrained to be within the bounds of the declared 149 type, but kept valid in the wider mode. The signedness of the 150 extension may differ from that of the type. */ 151 152 #define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ 153 if (GET_MODE_CLASS (MODE) == MODE_INT \ 154 && GET_MODE_SIZE (MODE) < 2) \ 155 (MODE) = HImode; 156 #endif 157 158 /* Layout of Source Language Data Types */ 159 160 #undef SIZE_TYPE 161 #define SIZE_TYPE (TARGET_LARGE ? "long unsigned int" : "unsigned int") 162 #undef PTRDIFF_TYPE 163 #define PTRDIFF_TYPE (TARGET_LARGE ? "long int" : "int") 164 #undef WCHAR_TYPE 165 #define WCHAR_TYPE "long int" 166 #undef WCHAR_TYPE_SIZE 167 #define WCHAR_TYPE_SIZE BITS_PER_WORD 168 #define FUNCTION_MODE HImode 169 #define CASE_VECTOR_MODE Pmode 170 #define HAS_LONG_COND_BRANCH 0 171 #define HAS_LONG_UNCOND_BRANCH 0 172 173 #define LOAD_EXTEND_OP(M) ZERO_EXTEND 174 /*#define WORD_REGISTER_OPERATIONS 1*/ 175 176 #define MOVE_MAX 8 177 #define STARTING_FRAME_OFFSET 0 178 179 #define INCOMING_RETURN_ADDR_RTX \ 180 msp430_incoming_return_addr_rtx () 181 182 #define RETURN_ADDR_RTX(COUNT, FA) \ 183 msp430_return_addr_rtx (COUNT) 184 185 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 186 187 #define SLOW_BYTE_ACCESS 0 188 189 190 /* Register Usage */ 191 192 /* gas doesn't recognize PC (R0), SP (R1), and SR (R2) as register 193 names. */ 194 #define REGISTER_NAMES \ 195 { \ 196 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", \ 197 "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", \ 198 "argptr" \ 199 } 200 201 enum reg_class 202 { 203 NO_REGS, 204 R12_REGS, 205 R13_REGS, 206 GEN_REGS, 207 ALL_REGS, 208 LIM_REG_CLASSES 209 }; 210 211 #define REG_CLASS_NAMES \ 212 { \ 213 "NO_REGS", \ 214 "R12_REGS", \ 215 "R13_REGS", \ 216 "GEN_REGS", \ 217 "ALL_REGS" \ 218 } 219 220 #define REG_CLASS_CONTENTS \ 221 { \ 222 0x00000000, \ 223 0x00001000, \ 224 0x00002000, \ 225 0x0000fff2, \ 226 0x0001ffff \ 227 } 228 229 #define GENERAL_REGS GEN_REGS 230 #define BASE_REG_CLASS GEN_REGS 231 #define INDEX_REG_CLASS GEN_REGS 232 #define N_REG_CLASSES (int) LIM_REG_CLASSES 233 234 #define PC_REGNUM 0 235 #define STACK_POINTER_REGNUM 1 236 #define CC_REGNUM 2 237 #define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */ 238 #define ARG_POINTER_REGNUM 16 239 #define STATIC_CHAIN_REGNUM 5 /* FIXME */ 240 241 #define FIRST_PSEUDO_REGISTER 17 242 243 #define REGNO_REG_CLASS(REGNO) ((REGNO) < 17 \ 244 ? GEN_REGS : NO_REGS) 245 246 #define TRAMPOLINE_SIZE 4 /* FIXME */ 247 #define TRAMPOLINE_ALIGNMENT 16 /* FIXME */ 248 249 #define ELIMINABLE_REGS \ 250 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \ 251 { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }, \ 252 { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }} 253 254 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 255 (OFFSET) = msp430_initial_elimination_offset ((FROM), (TO)) 256 257 258 #define FUNCTION_ARG_REGNO_P(N) ((N) >= 8 && (N) < ARG_POINTER_REGNUM) 259 #define DEFAULT_PCC_STRUCT_RETURN 0 260 261 /* 1 == register can't be used by gcc, in general 262 0 == register can be used by gcc, in general */ 263 #define FIXED_REGISTERS \ 264 { \ 265 1,0,1,1, 0,0,0,0, \ 266 0,0,0,0, 0,0,0,0, \ 267 1, \ 268 } 269 270 /* 1 == value changes across function calls 271 0 == value is the same after a call */ 272 /* R4 through R10 are callee-saved */ 273 #define CALL_USED_REGISTERS \ 274 { \ 275 1,0,1,1, 0,0,0,0, \ 276 0,0,0,1, 1,1,1,1, \ 277 1, \ 278 } 279 280 #define REG_ALLOC_ORDER \ 281 { 12, 13, 14, 15, 10, 9, 8, 7, 6, 5, 4, 11, 0, 1, 2, 3, 16 } 282 /* { 11, 15, 14, 13, 12, 10, 9, 8, 7, 6, 5, 4, 0, 1, 2, 3, 16 }*/ 283 284 #define REGNO_OK_FOR_BASE_P(regno) 1 285 #define REGNO_OK_FOR_INDEX_P(regno) 1 286 287 288 289 typedef struct 290 { 291 /* These two are the current argument status. */ 292 char reg_used[4]; 293 #define CA_FIRST_REG 12 294 char can_split; 295 /* These two are temporaries used internally. */ 296 char start_reg; 297 char reg_count; 298 char mem_count; 299 char special_p; 300 } CUMULATIVE_ARGS; 301 302 #define INIT_CUMULATIVE_ARGS(CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \ 303 msp430_init_cumulative_args (&CA, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) 304 305 306 /* FIXME */ 307 #define NO_PROFILE_COUNTERS 1 308 #define PROFILE_BEFORE_PROLOGUE 1 309 310 #define FUNCTION_PROFILER(FILE, LABELNO) \ 311 fprintf (FILE, "\tcall\t__mcount\n"); 312 313 #define HARD_REGNO_NREGS(REGNO, MODE) \ 314 msp430_hard_regno_nregs (REGNO, MODE) 315 316 #define HARD_REGNO_MODE_OK(REGNO, MODE) \ 317 msp430_hard_regno_mode_ok (REGNO, MODE) 318 319 #define MODES_TIEABLE_P(MODE1, MODE2) \ 320 msp430_modes_tieable_p (MODE1, MODE2) 321 322 /* Exception Handling */ 323 324 /* R12,R13,R14 - EH data 325 R15 - stack adjustment */ 326 327 #define EH_RETURN_DATA_REGNO(N) \ 328 (((N) < 3) ? ((N) + 12) : INVALID_REGNUM) 329 330 #define EH_RETURN_HANDLER_RTX \ 331 gen_rtx_MEM(Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG(Pmode, SP_REGNO), gen_rtx_REG (Pmode, 15))) 332 333 #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15) 334 335 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_udata4 336 337 338 /* Stack Layout and Calling Conventions */ 339 340 341 /* Addressing Modes */ 342 343 344 345 #define TEXT_SECTION_ASM_OP ".text" 346 #define DATA_SECTION_ASM_OP ".data" 347 #define BSS_SECTION_ASM_OP "\t.section .bss" 348 349 #define ASM_COMMENT_START " ;" 350 #define ASM_APP_ON "" 351 #define ASM_APP_OFF "" 352 #define LOCAL_LABEL_PREFIX ".L" 353 #undef USER_LABEL_PREFIX 354 #define USER_LABEL_PREFIX "" 355 356 #define GLOBAL_ASM_OP "\t.global\t" 357 358 #define ASM_OUTPUT_LABELREF(FILE, SYM) msp430_output_labelref ((FILE), (SYM)) 359 360 #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ 361 fprintf (FILE, "\t.long .L%d\n", VALUE) 362 363 /* This is how to output an element of a case-vector that is relative. 364 Note: The local label referenced by the "3b" below is emitted by 365 the tablejump insn. */ 366 367 #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ 368 fprintf (FILE, "\t.long .L%d - 1b\n", VALUE) 369 370 371 #define ASM_OUTPUT_ALIGN(STREAM, LOG) \ 372 do \ 373 { \ 374 if ((LOG) == 0) \ 375 break; \ 376 fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \ 377 } \ 378 while (0) 379 380 #define JUMP_TABLES_IN_TEXT_SECTION 1 381 382 #undef DWARF2_ADDR_SIZE 383 #define DWARF2_ADDR_SIZE 4 384 385 #define INCOMING_FRAME_SP_OFFSET (POINTER_SIZE / BITS_PER_UNIT) 386 387 #undef PREFERRED_DEBUGGING_TYPE 388 #define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG 389 390 #define DWARF2_ASM_LINE_DEBUG_INFO 1 391 392 /* Prevent reload (and others) from choosing HImode stack slots 393 when spilling hard registers when they may contain PSImode values. */ 394 #define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \ 395 ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode : choose_hard_reg_mode ((REGNO), (NREGS), false)) 396 397 /* Also stop GCC from thinking that it can eliminate (SUBREG:PSI (SI)). */ 398 #define CANNOT_CHANGE_MODE_CLASS(FROM,TO,CLASS) \ 399 ( ((TO) == PSImode && (FROM) == SImode) \ 400 || ((TO) == SImode && (FROM) == PSImode) \ 401 || ((TO) == DImode && (FROM) == PSImode) \ 402 || ((TO) == PSImode && (FROM) == DImode) \ 403 ) 404 405 #define ACCUMULATE_OUTGOING_ARGS 1 406 407 #undef ASM_DECLARE_FUNCTION_NAME 408 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ 409 msp430_start_function ((FILE), (NAME), (DECL)) 410 411 #define TARGET_HAS_NO_HW_DIVIDE (! TARGET_HWMULT) 412