1 /* Subroutines used for code generation on TI MSP430 processors. 2 Copyright (C) 2012-2017 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 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public 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 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "backend.h" 25 #include "target.h" 26 #include "rtl.h" 27 #include "tree.h" 28 #include "gimple-expr.h" 29 #include "df.h" 30 #include "memmodel.h" 31 #include "tm_p.h" 32 #include "regs.h" 33 #include "emit-rtl.h" 34 #include "diagnostic-core.h" 35 #include "fold-const.h" 36 #include "stor-layout.h" 37 #include "calls.h" 38 #include "output.h" 39 #include "explow.h" 40 #include "expr.h" 41 #include "langhooks.h" 42 #include "builtins.h" 43 44 /* This file should be included last. */ 45 #include "target-def.h" 46 47 48 static void msp430_compute_frame_info (void); 49 50 51 52 /* Run-time Target Specification. */ 53 54 bool msp430x = true; 55 56 struct GTY(()) machine_function 57 { 58 /* If set, the rest of the fields have been computed. */ 59 int computed; 60 /* Which registers need to be saved in the pro/epilogue. */ 61 int need_to_save [FIRST_PSEUDO_REGISTER]; 62 63 /* These fields describe the frame layout... */ 64 /* arg pointer */ 65 /* 2/4 bytes for saved PC */ 66 int framesize_regs; 67 /* frame pointer */ 68 int framesize_locals; 69 int framesize_outgoing; 70 /* stack pointer */ 71 int framesize; 72 73 /* How much we adjust the stack when returning from an exception 74 handler. */ 75 rtx eh_stack_adjust; 76 }; 77 78 /* This is our init_machine_status, as set in 79 msp_option_override. */ 80 static struct machine_function * 81 msp430_init_machine_status (void) 82 { 83 struct machine_function *m; 84 85 m = ggc_cleared_alloc<machine_function> (); 86 87 return m; 88 } 89 90 #undef TARGET_OPTION_OVERRIDE 91 #define TARGET_OPTION_OVERRIDE msp430_option_override 92 93 /* This is a copy of the same data structure found in gas/config/tc-msp430.c 94 Also another (sort-of) copy can be found in gcc/config/msp430/t-msp430 95 Keep these three structures in sync. 96 The data in this structure has been extracted from version 1.194 of the 97 devices.csv file released by TI in September 2016. */ 98 99 struct msp430_mcu_data 100 { 101 const char * name; 102 unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */ 103 unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */ 104 } 105 msp430_mcu_data [] = 106 { 107 { "cc430f5123",2,8 }, 108 { "cc430f5125",2,8 }, 109 { "cc430f5133",2,8 }, 110 { "cc430f5135",2,8 }, 111 { "cc430f5137",2,8 }, 112 { "cc430f5143",2,8 }, 113 { "cc430f5145",2,8 }, 114 { "cc430f5147",2,8 }, 115 { "cc430f6125",2,8 }, 116 { "cc430f6126",2,8 }, 117 { "cc430f6127",2,8 }, 118 { "cc430f6135",2,8 }, 119 { "cc430f6137",2,8 }, 120 { "cc430f6143",2,8 }, 121 { "cc430f6145",2,8 }, 122 { "cc430f6147",2,8 }, 123 { "msp430afe221",0,2 }, 124 { "msp430afe222",0,2 }, 125 { "msp430afe223",0,2 }, 126 { "msp430afe231",0,2 }, 127 { "msp430afe232",0,2 }, 128 { "msp430afe233",0,2 }, 129 { "msp430afe251",0,2 }, 130 { "msp430afe252",0,2 }, 131 { "msp430afe253",0,2 }, 132 { "msp430bt5190",2,8 }, 133 { "msp430c091",0,0 }, 134 { "msp430c092",0,0 }, 135 { "msp430c111",0,0 }, 136 { "msp430c1111",0,0 }, 137 { "msp430c112",0,0 }, 138 { "msp430c1121",0,0 }, 139 { "msp430c1331",0,0 }, 140 { "msp430c1351",0,0 }, 141 { "msp430c311s",0,0 }, 142 { "msp430c312",0,0 }, 143 { "msp430c313",0,0 }, 144 { "msp430c314",0,0 }, 145 { "msp430c315",0,0 }, 146 { "msp430c323",0,0 }, 147 { "msp430c325",0,0 }, 148 { "msp430c336",0,1 }, 149 { "msp430c337",0,1 }, 150 { "msp430c412",0,0 }, 151 { "msp430c413",0,0 }, 152 { "msp430cg4616",1,1 }, 153 { "msp430cg4617",1,1 }, 154 { "msp430cg4618",1,1 }, 155 { "msp430cg4619",1,1 }, 156 { "msp430e112",0,0 }, 157 { "msp430e313",0,0 }, 158 { "msp430e315",0,0 }, 159 { "msp430e325",0,0 }, 160 { "msp430e337",0,1 }, 161 { "msp430f110",0,0 }, 162 { "msp430f1101",0,0 }, 163 { "msp430f1101a",0,0 }, 164 { "msp430f1111",0,0 }, 165 { "msp430f1111a",0,0 }, 166 { "msp430f112",0,0 }, 167 { "msp430f1121",0,0 }, 168 { "msp430f1121a",0,0 }, 169 { "msp430f1122",0,0 }, 170 { "msp430f1132",0,0 }, 171 { "msp430f122",0,0 }, 172 { "msp430f1222",0,0 }, 173 { "msp430f123",0,0 }, 174 { "msp430f1232",0,0 }, 175 { "msp430f133",0,0 }, 176 { "msp430f135",0,0 }, 177 { "msp430f147",0,1 }, 178 { "msp430f1471",0,1 }, 179 { "msp430f148",0,1 }, 180 { "msp430f1481",0,1 }, 181 { "msp430f149",0,1 }, 182 { "msp430f1491",0,1 }, 183 { "msp430f155",0,0 }, 184 { "msp430f156",0,0 }, 185 { "msp430f157",0,0 }, 186 { "msp430f1610",0,1 }, 187 { "msp430f1611",0,1 }, 188 { "msp430f1612",0,1 }, 189 { "msp430f167",0,1 }, 190 { "msp430f168",0,1 }, 191 { "msp430f169",0,1 }, 192 { "msp430f2001",0,0 }, 193 { "msp430f2002",0,0 }, 194 { "msp430f2003",0,0 }, 195 { "msp430f2011",0,0 }, 196 { "msp430f2012",0,0 }, 197 { "msp430f2013",0,0 }, 198 { "msp430f2101",0,0 }, 199 { "msp430f2111",0,0 }, 200 { "msp430f2112",0,0 }, 201 { "msp430f2121",0,0 }, 202 { "msp430f2122",0,0 }, 203 { "msp430f2131",0,0 }, 204 { "msp430f2132",0,0 }, 205 { "msp430f2232",0,0 }, 206 { "msp430f2234",0,0 }, 207 { "msp430f2252",0,0 }, 208 { "msp430f2254",0,0 }, 209 { "msp430f2272",0,0 }, 210 { "msp430f2274",0,0 }, 211 { "msp430f233",0,2 }, 212 { "msp430f2330",0,2 }, 213 { "msp430f235",0,2 }, 214 { "msp430f2350",0,2 }, 215 { "msp430f2370",0,2 }, 216 { "msp430f2410",0,2 }, 217 { "msp430f2416",1,2 }, 218 { "msp430f2417",1,2 }, 219 { "msp430f2418",1,2 }, 220 { "msp430f2419",1,2 }, 221 { "msp430f247",0,2 }, 222 { "msp430f2471",0,2 }, 223 { "msp430f248",0,2 }, 224 { "msp430f2481",0,2 }, 225 { "msp430f249",0,2 }, 226 { "msp430f2491",0,2 }, 227 { "msp430f2616",1,2 }, 228 { "msp430f2617",1,2 }, 229 { "msp430f2618",1,2 }, 230 { "msp430f2619",1,2 }, 231 { "msp430f412",0,0 }, 232 { "msp430f413",0,0 }, 233 { "msp430f4132",0,0 }, 234 { "msp430f415",0,0 }, 235 { "msp430f4152",0,0 }, 236 { "msp430f417",0,0 }, 237 { "msp430f423",0,1 }, 238 { "msp430f423a",0,1 }, 239 { "msp430f425",0,1 }, 240 { "msp430f4250",0,0 }, 241 { "msp430f425a",0,1 }, 242 { "msp430f4260",0,0 }, 243 { "msp430f427",0,1 }, 244 { "msp430f4270",0,0 }, 245 { "msp430f427a",0,1 }, 246 { "msp430f435",0,0 }, 247 { "msp430f4351",0,0 }, 248 { "msp430f436",0,0 }, 249 { "msp430f4361",0,0 }, 250 { "msp430f437",0,0 }, 251 { "msp430f4371",0,0 }, 252 { "msp430f438",0,0 }, 253 { "msp430f439",0,0 }, 254 { "msp430f447",0,1 }, 255 { "msp430f448",0,1 }, 256 { "msp430f4481",0,1 }, 257 { "msp430f449",0,1 }, 258 { "msp430f4491",0,1 }, 259 { "msp430f4616",1,1 }, 260 { "msp430f46161",1,1 }, 261 { "msp430f4617",1,1 }, 262 { "msp430f46171",1,1 }, 263 { "msp430f4618",1,1 }, 264 { "msp430f46181",1,1 }, 265 { "msp430f4619",1,1 }, 266 { "msp430f46191",1,1 }, 267 { "msp430f47126",1,4 }, 268 { "msp430f47127",1,4 }, 269 { "msp430f47163",1,4 }, 270 { "msp430f47166",1,4 }, 271 { "msp430f47167",1,4 }, 272 { "msp430f47173",1,4 }, 273 { "msp430f47176",1,4 }, 274 { "msp430f47177",1,4 }, 275 { "msp430f47183",1,4 }, 276 { "msp430f47186",1,4 }, 277 { "msp430f47187",1,4 }, 278 { "msp430f47193",1,4 }, 279 { "msp430f47196",1,4 }, 280 { "msp430f47197",1,4 }, 281 { "msp430f477",0,0 }, 282 { "msp430f478",0,0 }, 283 { "msp430f4783",0,4 }, 284 { "msp430f4784",0,4 }, 285 { "msp430f479",0,0 }, 286 { "msp430f4793",0,4 }, 287 { "msp430f4794",0,4 }, 288 { "msp430f5131",2,8 }, 289 { "msp430f5132",2,8 }, 290 { "msp430f5151",2,8 }, 291 { "msp430f5152",2,8 }, 292 { "msp430f5171",2,8 }, 293 { "msp430f5172",2,8 }, 294 { "msp430f5212",2,8 }, 295 { "msp430f5213",2,8 }, 296 { "msp430f5214",2,8 }, 297 { "msp430f5217",2,8 }, 298 { "msp430f5218",2,8 }, 299 { "msp430f5219",2,8 }, 300 { "msp430f5222",2,8 }, 301 { "msp430f5223",2,8 }, 302 { "msp430f5224",2,8 }, 303 { "msp430f5227",2,8 }, 304 { "msp430f5228",2,8 }, 305 { "msp430f5229",2,8 }, 306 { "msp430f5232",2,8 }, 307 { "msp430f5234",2,8 }, 308 { "msp430f5237",2,8 }, 309 { "msp430f5239",2,8 }, 310 { "msp430f5242",2,8 }, 311 { "msp430f5244",2,8 }, 312 { "msp430f5247",2,8 }, 313 { "msp430f5249",2,8 }, 314 { "msp430f5252",2,8 }, 315 { "msp430f5253",2,8 }, 316 { "msp430f5254",2,8 }, 317 { "msp430f5255",2,8 }, 318 { "msp430f5256",2,8 }, 319 { "msp430f5257",2,8 }, 320 { "msp430f5258",2,8 }, 321 { "msp430f5259",2,8 }, 322 { "msp430f5304",2,8 }, 323 { "msp430f5308",2,8 }, 324 { "msp430f5309",2,8 }, 325 { "msp430f5310",2,8 }, 326 { "msp430f5324",2,8 }, 327 { "msp430f5325",2,8 }, 328 { "msp430f5326",2,8 }, 329 { "msp430f5327",2,8 }, 330 { "msp430f5328",2,8 }, 331 { "msp430f5329",2,8 }, 332 { "msp430f5333",2,8 }, 333 { "msp430f5335",2,8 }, 334 { "msp430f5336",2,8 }, 335 { "msp430f5338",2,8 }, 336 { "msp430f5340",2,8 }, 337 { "msp430f5341",2,8 }, 338 { "msp430f5342",2,8 }, 339 { "msp430f5358",2,8 }, 340 { "msp430f5359",2,8 }, 341 { "msp430f5418",2,8 }, 342 { "msp430f5418a",2,8 }, 343 { "msp430f5419",2,8 }, 344 { "msp430f5419a",2,8 }, 345 { "msp430f5435",2,8 }, 346 { "msp430f5435a",2,8 }, 347 { "msp430f5436",2,8 }, 348 { "msp430f5436a",2,8 }, 349 { "msp430f5437",2,8 }, 350 { "msp430f5437a",2,8 }, 351 { "msp430f5438",2,8 }, 352 { "msp430f5438a",2,8 }, 353 { "msp430f5500",2,8 }, 354 { "msp430f5501",2,8 }, 355 { "msp430f5502",2,8 }, 356 { "msp430f5503",2,8 }, 357 { "msp430f5504",2,8 }, 358 { "msp430f5505",2,8 }, 359 { "msp430f5506",2,8 }, 360 { "msp430f5507",2,8 }, 361 { "msp430f5508",2,8 }, 362 { "msp430f5509",2,8 }, 363 { "msp430f5510",2,8 }, 364 { "msp430f5513",2,8 }, 365 { "msp430f5514",2,8 }, 366 { "msp430f5515",2,8 }, 367 { "msp430f5517",2,8 }, 368 { "msp430f5519",2,8 }, 369 { "msp430f5521",2,8 }, 370 { "msp430f5522",2,8 }, 371 { "msp430f5524",2,8 }, 372 { "msp430f5525",2,8 }, 373 { "msp430f5526",2,8 }, 374 { "msp430f5527",2,8 }, 375 { "msp430f5528",2,8 }, 376 { "msp430f5529",2,8 }, 377 { "msp430f5630",2,8 }, 378 { "msp430f5631",2,8 }, 379 { "msp430f5632",2,8 }, 380 { "msp430f5633",2,8 }, 381 { "msp430f5634",2,8 }, 382 { "msp430f5635",2,8 }, 383 { "msp430f5636",2,8 }, 384 { "msp430f5637",2,8 }, 385 { "msp430f5638",2,8 }, 386 { "msp430f5658",2,8 }, 387 { "msp430f5659",2,8 }, 388 { "msp430f5xx_6xxgeneric",2,8 }, 389 { "msp430f6433",2,8 }, 390 { "msp430f6435",2,8 }, 391 { "msp430f6436",2,8 }, 392 { "msp430f6438",2,8 }, 393 { "msp430f6458",2,8 }, 394 { "msp430f6459",2,8 }, 395 { "msp430f6630",2,8 }, 396 { "msp430f6631",2,8 }, 397 { "msp430f6632",2,8 }, 398 { "msp430f6633",2,8 }, 399 { "msp430f6634",2,8 }, 400 { "msp430f6635",2,8 }, 401 { "msp430f6636",2,8 }, 402 { "msp430f6637",2,8 }, 403 { "msp430f6638",2,8 }, 404 { "msp430f6658",2,8 }, 405 { "msp430f6659",2,8 }, 406 { "msp430f6720",2,8 }, 407 { "msp430f6720a",2,8 }, 408 { "msp430f6721",2,8 }, 409 { "msp430f6721a",2,8 }, 410 { "msp430f6723",2,8 }, 411 { "msp430f6723a",2,8 }, 412 { "msp430f6724",2,8 }, 413 { "msp430f6724a",2,8 }, 414 { "msp430f6725",2,8 }, 415 { "msp430f6725a",2,8 }, 416 { "msp430f6726",2,8 }, 417 { "msp430f6726a",2,8 }, 418 { "msp430f6730",2,8 }, 419 { "msp430f6730a",2,8 }, 420 { "msp430f6731",2,8 }, 421 { "msp430f6731a",2,8 }, 422 { "msp430f6733",2,8 }, 423 { "msp430f6733a",2,8 }, 424 { "msp430f6734",2,8 }, 425 { "msp430f6734a",2,8 }, 426 { "msp430f6735",2,8 }, 427 { "msp430f6735a",2,8 }, 428 { "msp430f6736",2,8 }, 429 { "msp430f6736a",2,8 }, 430 { "msp430f6745",2,8 }, 431 { "msp430f67451",2,8 }, 432 { "msp430f67451a",2,8 }, 433 { "msp430f6745a",2,8 }, 434 { "msp430f6746",2,8 }, 435 { "msp430f67461",2,8 }, 436 { "msp430f67461a",2,8 }, 437 { "msp430f6746a",2,8 }, 438 { "msp430f6747",2,8 }, 439 { "msp430f67471",2,8 }, 440 { "msp430f67471a",2,8 }, 441 { "msp430f6747a",2,8 }, 442 { "msp430f6748",2,8 }, 443 { "msp430f67481",2,8 }, 444 { "msp430f67481a",2,8 }, 445 { "msp430f6748a",2,8 }, 446 { "msp430f6749",2,8 }, 447 { "msp430f67491",2,8 }, 448 { "msp430f67491a",2,8 }, 449 { "msp430f6749a",2,8 }, 450 { "msp430f67621",2,8 }, 451 { "msp430f67621a",2,8 }, 452 { "msp430f67641",2,8 }, 453 { "msp430f67641a",2,8 }, 454 { "msp430f6765",2,8 }, 455 { "msp430f67651",2,8 }, 456 { "msp430f67651a",2,8 }, 457 { "msp430f6765a",2,8 }, 458 { "msp430f6766",2,8 }, 459 { "msp430f67661",2,8 }, 460 { "msp430f67661a",2,8 }, 461 { "msp430f6766a",2,8 }, 462 { "msp430f6767",2,8 }, 463 { "msp430f67671",2,8 }, 464 { "msp430f67671a",2,8 }, 465 { "msp430f6767a",2,8 }, 466 { "msp430f6768",2,8 }, 467 { "msp430f67681",2,8 }, 468 { "msp430f67681a",2,8 }, 469 { "msp430f6768a",2,8 }, 470 { "msp430f6769",2,8 }, 471 { "msp430f67691",2,8 }, 472 { "msp430f67691a",2,8 }, 473 { "msp430f6769a",2,8 }, 474 { "msp430f6775",2,8 }, 475 { "msp430f67751",2,8 }, 476 { "msp430f67751a",2,8 }, 477 { "msp430f6775a",2,8 }, 478 { "msp430f6776",2,8 }, 479 { "msp430f67761",2,8 }, 480 { "msp430f67761a",2,8 }, 481 { "msp430f6776a",2,8 }, 482 { "msp430f6777",2,8 }, 483 { "msp430f67771",2,8 }, 484 { "msp430f67771a",2,8 }, 485 { "msp430f6777a",2,8 }, 486 { "msp430f6778",2,8 }, 487 { "msp430f67781",2,8 }, 488 { "msp430f67781a",2,8 }, 489 { "msp430f6778a",2,8 }, 490 { "msp430f6779",2,8 }, 491 { "msp430f67791",2,8 }, 492 { "msp430f67791a",2,8 }, 493 { "msp430f6779a",2,8 }, 494 { "msp430fe423",0,0 }, 495 { "msp430fe4232",0,0 }, 496 { "msp430fe423a",0,0 }, 497 { "msp430fe4242",0,0 }, 498 { "msp430fe425",0,0 }, 499 { "msp430fe4252",0,0 }, 500 { "msp430fe425a",0,0 }, 501 { "msp430fe427",0,0 }, 502 { "msp430fe4272",0,0 }, 503 { "msp430fe427a",0,0 }, 504 { "msp430fg4250",0,0 }, 505 { "msp430fg4260",0,0 }, 506 { "msp430fg4270",0,0 }, 507 { "msp430fg437",0,0 }, 508 { "msp430fg438",0,0 }, 509 { "msp430fg439",0,0 }, 510 { "msp430fg4616",1,1 }, 511 { "msp430fg4617",1,1 }, 512 { "msp430fg4618",1,1 }, 513 { "msp430fg4619",1,1 }, 514 { "msp430fg477",0,0 }, 515 { "msp430fg478",0,0 }, 516 { "msp430fg479",0,0 }, 517 { "msp430fg6425",2,8 }, 518 { "msp430fg6426",2,8 }, 519 { "msp430fg6625",2,8 }, 520 { "msp430fg6626",2,8 }, 521 { "msp430fr2032",2,0 }, 522 { "msp430fr2033",2,0 }, 523 { "msp430fr2110",2,0 }, 524 { "msp430fr2111",2,0 }, 525 { "msp430fr2310",2,0 }, 526 { "msp430fr2311",2,0 }, 527 { "msp430fr2433",2,8 }, 528 { "msp430fr2532",2,8 }, 529 { "msp430fr2533",2,8 }, 530 { "msp430fr2632",2,8 }, 531 { "msp430fr2633",2,8 }, 532 { "msp430fr2xx_4xxgeneric",2,8 }, 533 { "msp430fr4131",2,0 }, 534 { "msp430fr4132",2,0 }, 535 { "msp430fr4133",2,0 }, 536 { "msp430fr5720",2,8 }, 537 { "msp430fr5721",2,8 }, 538 { "msp430fr5722",2,8 }, 539 { "msp430fr5723",2,8 }, 540 { "msp430fr5724",2,8 }, 541 { "msp430fr5725",2,8 }, 542 { "msp430fr5726",2,8 }, 543 { "msp430fr5727",2,8 }, 544 { "msp430fr5728",2,8 }, 545 { "msp430fr5729",2,8 }, 546 { "msp430fr5730",2,8 }, 547 { "msp430fr5731",2,8 }, 548 { "msp430fr5732",2,8 }, 549 { "msp430fr5733",2,8 }, 550 { "msp430fr5734",2,8 }, 551 { "msp430fr5735",2,8 }, 552 { "msp430fr5736",2,8 }, 553 { "msp430fr5737",2,8 }, 554 { "msp430fr5738",2,8 }, 555 { "msp430fr5739",2,8 }, 556 { "msp430fr57xxgeneric",2,8 }, 557 { "msp430fr5847",2,8 }, 558 { "msp430fr58471",2,8 }, 559 { "msp430fr5848",2,8 }, 560 { "msp430fr5849",2,8 }, 561 { "msp430fr5857",2,8 }, 562 { "msp430fr5858",2,8 }, 563 { "msp430fr5859",2,8 }, 564 { "msp430fr5867",2,8 }, 565 { "msp430fr58671",2,8 }, 566 { "msp430fr5868",2,8 }, 567 { "msp430fr5869",2,8 }, 568 { "msp430fr5870",2,8 }, 569 { "msp430fr5872",2,8 }, 570 { "msp430fr58721",2,8 }, 571 { "msp430fr5887",2,8 }, 572 { "msp430fr5888",2,8 }, 573 { "msp430fr5889",2,8 }, 574 { "msp430fr58891",2,8 }, 575 { "msp430fr5922",2,8 }, 576 { "msp430fr59221",2,8 }, 577 { "msp430fr5947",2,8 }, 578 { "msp430fr59471",2,8 }, 579 { "msp430fr5948",2,8 }, 580 { "msp430fr5949",2,8 }, 581 { "msp430fr5957",2,8 }, 582 { "msp430fr5958",2,8 }, 583 { "msp430fr5959",2,8 }, 584 { "msp430fr5962",2,8 }, 585 { "msp430fr5964",2,8 }, 586 { "msp430fr5967",2,8 }, 587 { "msp430fr5968",2,8 }, 588 { "msp430fr5969",2,8 }, 589 { "msp430fr59691",2,8 }, 590 { "msp430fr5970",2,8 }, 591 { "msp430fr5972",2,8 }, 592 { "msp430fr59721",2,8 }, 593 { "msp430fr5986",2,8 }, 594 { "msp430fr5987",2,8 }, 595 { "msp430fr5988",2,8 }, 596 { "msp430fr5989",2,8 }, 597 { "msp430fr59891",2,8 }, 598 { "msp430fr5992",2,8 }, 599 { "msp430fr5994",2,8 }, 600 { "msp430fr59941",2,8 }, 601 { "msp430fr5xx_6xxgeneric",2,8 }, 602 { "msp430fr6820",2,8 }, 603 { "msp430fr6822",2,8 }, 604 { "msp430fr68221",2,8 }, 605 { "msp430fr6870",2,8 }, 606 { "msp430fr6872",2,8 }, 607 { "msp430fr68721",2,8 }, 608 { "msp430fr6877",2,8 }, 609 { "msp430fr6879",2,8 }, 610 { "msp430fr68791",2,8 }, 611 { "msp430fr6887",2,8 }, 612 { "msp430fr6888",2,8 }, 613 { "msp430fr6889",2,8 }, 614 { "msp430fr68891",2,8 }, 615 { "msp430fr6920",2,8 }, 616 { "msp430fr6922",2,8 }, 617 { "msp430fr69221",2,8 }, 618 { "msp430fr6927",2,8 }, 619 { "msp430fr69271",2,8 }, 620 { "msp430fr6928",2,8 }, 621 { "msp430fr6970",2,8 }, 622 { "msp430fr6972",2,8 }, 623 { "msp430fr69721",2,8 }, 624 { "msp430fr6977",2,8 }, 625 { "msp430fr6979",2,8 }, 626 { "msp430fr69791",2,8 }, 627 { "msp430fr6987",2,8 }, 628 { "msp430fr6988",2,8 }, 629 { "msp430fr6989",2,8 }, 630 { "msp430fr69891",2,8 }, 631 { "msp430fw423",0,0 }, 632 { "msp430fw425",0,0 }, 633 { "msp430fw427",0,0 }, 634 { "msp430fw428",0,0 }, 635 { "msp430fw429",0,0 }, 636 { "msp430g2001",0,0 }, 637 { "msp430g2101",0,0 }, 638 { "msp430g2102",0,0 }, 639 { "msp430g2111",0,0 }, 640 { "msp430g2112",0,0 }, 641 { "msp430g2113",0,0 }, 642 { "msp430g2121",0,0 }, 643 { "msp430g2131",0,0 }, 644 { "msp430g2132",0,0 }, 645 { "msp430g2152",0,0 }, 646 { "msp430g2153",0,0 }, 647 { "msp430g2201",0,0 }, 648 { "msp430g2202",0,0 }, 649 { "msp430g2203",0,0 }, 650 { "msp430g2210",0,0 }, 651 { "msp430g2211",0,0 }, 652 { "msp430g2212",0,0 }, 653 { "msp430g2213",0,0 }, 654 { "msp430g2221",0,0 }, 655 { "msp430g2230",0,0 }, 656 { "msp430g2231",0,0 }, 657 { "msp430g2232",0,0 }, 658 { "msp430g2233",0,0 }, 659 { "msp430g2252",0,0 }, 660 { "msp430g2253",0,0 }, 661 { "msp430g2302",0,0 }, 662 { "msp430g2303",0,0 }, 663 { "msp430g2312",0,0 }, 664 { "msp430g2313",0,0 }, 665 { "msp430g2332",0,0 }, 666 { "msp430g2333",0,0 }, 667 { "msp430g2352",0,0 }, 668 { "msp430g2353",0,0 }, 669 { "msp430g2402",0,0 }, 670 { "msp430g2403",0,0 }, 671 { "msp430g2412",0,0 }, 672 { "msp430g2413",0,0 }, 673 { "msp430g2432",0,0 }, 674 { "msp430g2433",0,0 }, 675 { "msp430g2444",0,0 }, 676 { "msp430g2452",0,0 }, 677 { "msp430g2453",0,0 }, 678 { "msp430g2513",0,0 }, 679 { "msp430g2533",0,0 }, 680 { "msp430g2544",0,0 }, 681 { "msp430g2553",0,0 }, 682 { "msp430g2744",0,0 }, 683 { "msp430g2755",0,0 }, 684 { "msp430g2855",0,0 }, 685 { "msp430g2955",0,0 }, 686 { "msp430i2020",0,2 }, 687 { "msp430i2021",0,2 }, 688 { "msp430i2030",0,2 }, 689 { "msp430i2031",0,2 }, 690 { "msp430i2040",0,2 }, 691 { "msp430i2041",0,2 }, 692 { "msp430i2xxgeneric",0,2 }, 693 { "msp430l092",0,0 }, 694 { "msp430p112",0,0 }, 695 { "msp430p313",0,0 }, 696 { "msp430p315",0,0 }, 697 { "msp430p315s",0,0 }, 698 { "msp430p325",0,0 }, 699 { "msp430p337",0,1 }, 700 { "msp430sl5438a",2,8 }, 701 { "msp430tch5e",0,0 }, 702 { "msp430xgeneric",2,8 }, 703 { "rf430f5144",2,8 }, 704 { "rf430f5155",2,8 }, 705 { "rf430f5175",2,8 }, 706 { "rf430frl152h",0,0 }, 707 { "rf430frl152h_rom",0,0 }, 708 { "rf430frl153h",0,0 }, 709 { "rf430frl153h_rom",0,0 }, 710 { "rf430frl154h",0,0 }, 711 { "rf430frl154h_rom",0,0 } 712 }; 713 714 /* Generate a C preprocessor symbol based upon the MCU selected by the user. 715 If a specific MCU has not been selected then return a generic symbol instead. */ 716 717 const char * 718 msp430_mcu_name (void) 719 { 720 if (target_mcu) 721 { 722 unsigned int i; 723 static char mcu_name [64]; 724 725 snprintf (mcu_name, sizeof (mcu_name) - 1, "__%s__", target_mcu); 726 for (i = strlen (mcu_name); i--;) 727 mcu_name[i] = TOUPPER (mcu_name[i]); 728 return mcu_name; 729 } 730 731 return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__"; 732 } 733 734 static const char * 735 hwmult_name (unsigned int val) 736 { 737 switch (val) 738 { 739 case 0: return "none"; 740 case 1: return "16-bit"; 741 case 2: return "16-bit"; 742 case 4: return "32-bit"; 743 case 8: return "32-bit (5xx)"; 744 default: gcc_unreachable (); 745 } 746 } 747 748 static void 749 msp430_option_override (void) 750 { 751 init_machine_status = msp430_init_machine_status; 752 753 if (target_cpu) 754 { 755 /* gcc/common/config/msp430-common.c will have 756 already canonicalised the string in target_cpu. */ 757 if (strcasecmp (target_cpu, "msp430x") == 0) 758 msp430x = true; 759 else /* target_cpu == "msp430" - already handled by the front end. */ 760 msp430x = false; 761 } 762 763 if (target_mcu) 764 { 765 int i; 766 767 /* FIXME: If the array were alpha sorted, we could use a binary search. */ 768 for (i = ARRAY_SIZE (msp430_mcu_data); i--;) 769 if (strcasecmp (msp430_mcu_data[i].name, target_mcu) == 0) 770 { 771 bool xisa = msp430_mcu_data[i].revision >= 1; 772 773 if (msp430_warn_mcu) 774 { 775 if (target_cpu&& msp430x != xisa) 776 warning (0, "MCU '%s' supports %s ISA but -mcpu option is set to %s", 777 target_mcu, xisa ? "430X" : "430", msp430x ? "430X" : "430"); 778 779 if (msp430_mcu_data[i].hwmpy == 0 780 && msp430_hwmult_type != MSP430_HWMULT_AUTO 781 && msp430_hwmult_type != MSP430_HWMULT_NONE) 782 warning (0, "MCU '%s' does not have hardware multiply support, but -mhwmult is set to %s", 783 target_mcu, 784 msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit" 785 : msp430_hwmult_type == MSP430_HWMULT_LARGE ? "32-bit" : "f5series"); 786 else if (msp430_hwmult_type == MSP430_HWMULT_SMALL 787 && msp430_mcu_data[i].hwmpy != 1 788 && msp430_mcu_data[i].hwmpy != 2 ) 789 warning (0, "MCU '%s' supports %s hardware multiply, but -mhwmult is set to 16-bit", 790 target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy)); 791 else if (msp430_hwmult_type == MSP430_HWMULT_LARGE && msp430_mcu_data[i].hwmpy != 4) 792 warning (0, "MCU '%s' supports %s hardware multiply, but -mhwmult is set to 32-bit", 793 target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy)); 794 else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES && msp430_mcu_data[i].hwmpy != 8) 795 warning (0, "MCU '%s' supports %s hardware multiply, but -mhwmult is set to f5series", 796 target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy)); 797 } 798 799 msp430x = xisa; 800 break; 801 } 802 803 if (i < 0) 804 { 805 if (msp430_hwmult_type == MSP430_HWMULT_AUTO) 806 { 807 if (msp430_warn_mcu) 808 { 809 if (target_cpu == NULL) 810 warning (0, 811 "Unrecognized MCU name '%s', assuming that it is " 812 "just a MSP430 with no hardware multiply.\n" 813 "Use the -mcpu and -mhwmult options to set " 814 "these explicitly.", 815 target_mcu); 816 else 817 warning (0, 818 "Unrecognized MCU name '%s', assuming that it " 819 "has no hardware multiply.\nUse the -mhwmult " 820 "option to set this explicitly.", 821 target_mcu); 822 } 823 824 msp430_hwmult_type = MSP430_HWMULT_NONE; 825 } 826 else if (target_cpu == NULL) 827 { 828 if (msp430_warn_mcu) 829 warning (0, 830 "Unrecognized MCU name '%s', assuming that it just " 831 "supports the MSP430 ISA.\nUse the -mcpu option to " 832 "set the ISA explicitly.", 833 target_mcu); 834 835 msp430x = false; 836 } 837 else if (msp430_warn_mcu) 838 warning (0, "Unrecognized MCU name '%s'.", target_mcu); 839 } 840 } 841 842 /* The F5 series are all able to support the 430X ISA. */ 843 if (target_cpu == NULL && target_mcu == NULL && msp430_hwmult_type == MSP430_HWMULT_F5SERIES) 844 msp430x = true; 845 846 if (TARGET_LARGE && !msp430x) 847 error ("-mlarge requires a 430X-compatible -mmcu="); 848 849 if (msp430_code_region == MSP430_REGION_UPPER && ! msp430x) 850 error ("-mcode-region=upper requires 430X-compatible cpu"); 851 if (msp430_data_region == MSP430_REGION_UPPER && ! msp430x) 852 error ("-mdata-region=upper requires 430X-compatible cpu"); 853 854 if (flag_exceptions || flag_non_call_exceptions 855 || flag_unwind_tables || flag_asynchronous_unwind_tables) 856 flag_omit_frame_pointer = false; 857 else 858 flag_omit_frame_pointer = true; 859 860 /* This is a hack to work around a problem with the newlib build 861 mechanism. Newlib always appends CFLAGS to the end of the GCC 862 command line and always sets -O2 in CFLAGS. Thus it is not 863 possible to build newlib with -Os enabled. Until now... */ 864 if (TARGET_OPT_SPACE && optimize < 3) 865 optimize_size = 1; 866 } 867 868 #undef TARGET_SCALAR_MODE_SUPPORTED_P 869 #define TARGET_SCALAR_MODE_SUPPORTED_P msp430_scalar_mode_supported_p 870 871 static bool 872 msp430_scalar_mode_supported_p (machine_mode m) 873 { 874 if (m == PSImode && msp430x) 875 return true; 876 #if 0 877 if (m == TImode) 878 return true; 879 #endif 880 return default_scalar_mode_supported_p (m); 881 } 882 883 884 885 /* Storage Layout */ 886 887 #undef TARGET_MS_BITFIELD_LAYOUT_P 888 #define TARGET_MS_BITFIELD_LAYOUT_P msp430_ms_bitfield_layout_p 889 890 bool 891 msp430_ms_bitfield_layout_p (const_tree record_type ATTRIBUTE_UNUSED) 892 { 893 return false; 894 } 895 896 897 898 /* Register Usage */ 899 900 /* Implements HARD_REGNO_NREGS. MSP430X registers can hold a single 901 PSImode value, but not an SImode value. */ 902 int 903 msp430_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, 904 machine_mode mode) 905 { 906 if (mode == PSImode && msp430x) 907 return 1; 908 if (mode == CPSImode && msp430x) 909 return 2; 910 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) 911 / UNITS_PER_WORD); 912 } 913 914 /* Implements HARD_REGNO_NREGS_HAS_PADDING. */ 915 int 916 msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED, 917 machine_mode mode) 918 { 919 if (mode == PSImode && msp430x) 920 return 1; 921 return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) 922 / UNITS_PER_WORD); 923 } 924 925 /* Implements HARD_REGNO_NREGS_WITH_PADDING. */ 926 int 927 msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED, 928 machine_mode mode) 929 { 930 if (mode == PSImode) 931 return 2; 932 if (mode == CPSImode) 933 return 4; 934 return msp430_hard_regno_nregs (regno, mode); 935 } 936 937 /* Implements HARD_REGNO_MODE_OK. */ 938 int 939 msp430_hard_regno_mode_ok (int regno ATTRIBUTE_UNUSED, 940 machine_mode mode) 941 { 942 return regno <= (ARG_POINTER_REGNUM - msp430_hard_regno_nregs (regno, mode)); 943 } 944 945 /* Implements MODES_TIEABLE_P. */ 946 bool 947 msp430_modes_tieable_p (machine_mode mode1, machine_mode mode2) 948 { 949 if ((mode1 == PSImode || mode2 == SImode) 950 || (mode1 == SImode || mode2 == PSImode)) 951 return false; 952 953 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT 954 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT) 955 == (GET_MODE_CLASS (mode2) == MODE_FLOAT 956 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT)); 957 } 958 959 #undef TARGET_FRAME_POINTER_REQUIRED 960 #define TARGET_FRAME_POINTER_REQUIRED msp430_frame_pointer_required 961 962 static bool 963 msp430_frame_pointer_required (void) 964 { 965 return false; 966 } 967 968 #undef TARGET_CAN_ELIMINATE 969 #define TARGET_CAN_ELIMINATE msp430_can_eliminate 970 971 static bool 972 msp430_can_eliminate (const int from_reg ATTRIBUTE_UNUSED, 973 const int to_reg ATTRIBUTE_UNUSED) 974 { 975 return true; 976 } 977 978 /* Implements INITIAL_ELIMINATION_OFFSET. */ 979 int 980 msp430_initial_elimination_offset (int from, int to) 981 { 982 int rv = 0; /* As if arg to arg. */ 983 984 msp430_compute_frame_info (); 985 986 switch (to) 987 { 988 case STACK_POINTER_REGNUM: 989 rv += cfun->machine->framesize_outgoing; 990 rv += cfun->machine->framesize_locals; 991 /* Fall through. */ 992 case FRAME_POINTER_REGNUM: 993 rv += cfun->machine->framesize_regs; 994 /* Allow for the saved return address. */ 995 rv += (TARGET_LARGE ? 4 : 2); 996 /* NB/ No need to allow for crtl->args.pretend_args_size. 997 GCC does that for us. */ 998 break; 999 default: 1000 gcc_unreachable (); 1001 } 1002 1003 switch (from) 1004 { 1005 case FRAME_POINTER_REGNUM: 1006 /* Allow for the fall through above. */ 1007 rv -= (TARGET_LARGE ? 4 : 2); 1008 rv -= cfun->machine->framesize_regs; 1009 case ARG_POINTER_REGNUM: 1010 break; 1011 default: 1012 gcc_unreachable (); 1013 } 1014 1015 return rv; 1016 } 1017 1018 /* Named Address Space support */ 1019 1020 1021 /* Return the appropriate mode for a named address pointer. */ 1022 #undef TARGET_ADDR_SPACE_POINTER_MODE 1023 #define TARGET_ADDR_SPACE_POINTER_MODE msp430_addr_space_pointer_mode 1024 #undef TARGET_ADDR_SPACE_ADDRESS_MODE 1025 #define TARGET_ADDR_SPACE_ADDRESS_MODE msp430_addr_space_pointer_mode 1026 1027 static machine_mode 1028 msp430_addr_space_pointer_mode (addr_space_t addrspace) 1029 { 1030 switch (addrspace) 1031 { 1032 default: 1033 case ADDR_SPACE_GENERIC: 1034 return Pmode; 1035 case ADDR_SPACE_NEAR: 1036 return HImode; 1037 case ADDR_SPACE_FAR: 1038 return PSImode; 1039 } 1040 } 1041 1042 /* Function pointers are stored in unwind_word sized 1043 variables, so make sure that unwind_word is big enough. */ 1044 #undef TARGET_UNWIND_WORD_MODE 1045 #define TARGET_UNWIND_WORD_MODE msp430_unwind_word_mode 1046 1047 static machine_mode 1048 msp430_unwind_word_mode (void) 1049 { 1050 /* This needs to match msp430_init_dwarf_reg_sizes_extra (below). */ 1051 return msp430x ? PSImode : HImode; 1052 } 1053 1054 /* Determine if one named address space is a subset of another. */ 1055 #undef TARGET_ADDR_SPACE_SUBSET_P 1056 #define TARGET_ADDR_SPACE_SUBSET_P msp430_addr_space_subset_p 1057 static bool 1058 msp430_addr_space_subset_p (addr_space_t subset, addr_space_t superset) 1059 { 1060 if (subset == superset) 1061 return true; 1062 else 1063 return (subset != ADDR_SPACE_FAR && superset == ADDR_SPACE_FAR); 1064 } 1065 1066 #undef TARGET_ADDR_SPACE_CONVERT 1067 #define TARGET_ADDR_SPACE_CONVERT msp430_addr_space_convert 1068 /* Convert from one address space to another. */ 1069 static rtx 1070 msp430_addr_space_convert (rtx op, tree from_type, tree to_type) 1071 { 1072 addr_space_t from_as = TYPE_ADDR_SPACE (TREE_TYPE (from_type)); 1073 addr_space_t to_as = TYPE_ADDR_SPACE (TREE_TYPE (to_type)); 1074 rtx result; 1075 1076 if (to_as != ADDR_SPACE_FAR && from_as == ADDR_SPACE_FAR) 1077 { 1078 /* This is unpredictable, as we're truncating off usable address 1079 bits. */ 1080 1081 if (CONSTANT_P (op)) 1082 return gen_rtx_CONST (HImode, op); 1083 1084 result = gen_reg_rtx (HImode); 1085 emit_insn (gen_truncpsihi2 (result, op)); 1086 return result; 1087 } 1088 else if (to_as == ADDR_SPACE_FAR && from_as != ADDR_SPACE_FAR) 1089 { 1090 /* This always works. */ 1091 1092 if (CONSTANT_P (op)) 1093 return gen_rtx_CONST (PSImode, op); 1094 1095 result = gen_reg_rtx (PSImode); 1096 emit_insn (gen_zero_extendhipsi2 (result, op)); 1097 return result; 1098 } 1099 else 1100 gcc_unreachable (); 1101 } 1102 1103 /* Stack Layout and Calling Conventions. */ 1104 1105 /* For each function, we list the gcc version and the TI version on 1106 each line, where we're converting the function names. */ 1107 static char const * const special_convention_function_names [] = 1108 { 1109 "__muldi3", "__mspabi_mpyll", 1110 "__udivdi3", "__mspabi_divull", 1111 "__umoddi3", "__mspabi_remull", 1112 "__divdi3", "__mspabi_divlli", 1113 "__moddi3", "__mspabi_remlli", 1114 "__mspabi_srall", 1115 "__mspabi_srlll", 1116 "__mspabi_sllll", 1117 "__adddf3", "__mspabi_addd", 1118 "__subdf3", "__mspabi_subd", 1119 "__muldf3", "__mspabi_mpyd", 1120 "__divdf3", "__mspabi_divd", 1121 "__mspabi_cmpd", 1122 NULL 1123 }; 1124 1125 /* TRUE if the function passed is a "speical" function. Special 1126 functions pass two DImode parameters in registers. */ 1127 static bool 1128 msp430_special_register_convention_p (const char *name) 1129 { 1130 int i; 1131 1132 for (i = 0; special_convention_function_names [i]; i++) 1133 if (! strcmp (name, special_convention_function_names [i])) 1134 return true; 1135 1136 return false; 1137 } 1138 1139 #undef TARGET_FUNCTION_VALUE_REGNO_P 1140 #define TARGET_FUNCTION_VALUE_REGNO_P msp430_function_value_regno_p 1141 1142 bool 1143 msp430_function_value_regno_p (unsigned int regno) 1144 { 1145 return regno == 12; 1146 } 1147 1148 1149 #undef TARGET_FUNCTION_VALUE 1150 #define TARGET_FUNCTION_VALUE msp430_function_value 1151 1152 rtx 1153 msp430_function_value (const_tree ret_type, 1154 const_tree fn_decl_or_type ATTRIBUTE_UNUSED, 1155 bool outgoing ATTRIBUTE_UNUSED) 1156 { 1157 return gen_rtx_REG (TYPE_MODE (ret_type), 12); 1158 } 1159 1160 #undef TARGET_LIBCALL_VALUE 1161 #define TARGET_LIBCALL_VALUE msp430_libcall_value 1162 1163 rtx 1164 msp430_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED) 1165 { 1166 return gen_rtx_REG (mode, 12); 1167 } 1168 1169 /* Implements INIT_CUMULATIVE_ARGS. */ 1170 void 1171 msp430_init_cumulative_args (CUMULATIVE_ARGS *ca, 1172 tree fntype ATTRIBUTE_UNUSED, 1173 rtx libname ATTRIBUTE_UNUSED, 1174 tree fndecl ATTRIBUTE_UNUSED, 1175 int n_named_args ATTRIBUTE_UNUSED) 1176 { 1177 const char *fname; 1178 memset (ca, 0, sizeof(*ca)); 1179 1180 ca->can_split = 1; 1181 1182 if (fndecl) 1183 fname = IDENTIFIER_POINTER (DECL_NAME (fndecl)); 1184 else if (libname) 1185 fname = XSTR (libname, 0); 1186 else 1187 fname = NULL; 1188 1189 if (fname && msp430_special_register_convention_p (fname)) 1190 ca->special_p = 1; 1191 } 1192 1193 /* Helper function for argument passing; this function is the common 1194 code that determines where an argument will be passed. */ 1195 static void 1196 msp430_evaluate_arg (cumulative_args_t cap, 1197 machine_mode mode, 1198 const_tree type ATTRIBUTE_UNUSED, 1199 bool named) 1200 { 1201 CUMULATIVE_ARGS *ca = get_cumulative_args (cap); 1202 int nregs = GET_MODE_SIZE (mode); 1203 int i; 1204 1205 ca->reg_count = 0; 1206 ca->mem_count = 0; 1207 1208 if (!named) 1209 return; 1210 1211 if (mode == PSImode) 1212 nregs = 1; 1213 else 1214 nregs = (nregs + 1) / 2; 1215 1216 if (ca->special_p) 1217 { 1218 /* Function is passed two DImode operands, in R8:R11 and 1219 R12:15. */ 1220 ca->start_reg = 8; 1221 ca->reg_count = 4; 1222 return; 1223 } 1224 1225 switch (nregs) 1226 { 1227 case 1: 1228 for (i = 0; i < 4; i++) 1229 if (! ca->reg_used [i]) 1230 { 1231 ca->reg_count = 1; 1232 ca->start_reg = CA_FIRST_REG + i; 1233 return; 1234 } 1235 break; 1236 case 2: 1237 for (i = 0; i < 3; i++) 1238 if (! ca->reg_used [i] && ! ca->reg_used [i + 1]) 1239 { 1240 ca->reg_count = 2; 1241 ca->start_reg = CA_FIRST_REG + i; 1242 return; 1243 } 1244 if (! ca->reg_used [3] && ca->can_split) 1245 { 1246 ca->reg_count = 1; 1247 ca->mem_count = 2; 1248 ca->start_reg = CA_FIRST_REG + 3; 1249 return; 1250 } 1251 break; 1252 case 3: 1253 case 4: 1254 ca->can_split = 0; 1255 if (! ca->reg_used [0] 1256 && ! ca->reg_used [1] 1257 && ! ca->reg_used [2] 1258 && ! ca->reg_used [3]) 1259 { 1260 ca->reg_count = 4; 1261 ca->start_reg = CA_FIRST_REG; 1262 return; 1263 } 1264 break; 1265 } 1266 } 1267 1268 #undef TARGET_PROMOTE_PROTOTYPES 1269 #define TARGET_PROMOTE_PROTOTYPES msp430_promote_prototypes 1270 1271 bool 1272 msp430_promote_prototypes (const_tree fntype ATTRIBUTE_UNUSED) 1273 { 1274 return false; 1275 } 1276 1277 #undef TARGET_FUNCTION_ARG 1278 #define TARGET_FUNCTION_ARG msp430_function_arg 1279 1280 rtx 1281 msp430_function_arg (cumulative_args_t cap, 1282 machine_mode mode, 1283 const_tree type, 1284 bool named) 1285 { 1286 CUMULATIVE_ARGS *ca = get_cumulative_args (cap); 1287 1288 msp430_evaluate_arg (cap, mode, type, named); 1289 1290 if (ca->reg_count) 1291 return gen_rtx_REG (mode, ca->start_reg); 1292 1293 return 0; 1294 } 1295 1296 #undef TARGET_ARG_PARTIAL_BYTES 1297 #define TARGET_ARG_PARTIAL_BYTES msp430_arg_partial_bytes 1298 1299 int 1300 msp430_arg_partial_bytes (cumulative_args_t cap, 1301 machine_mode mode, 1302 tree type, 1303 bool named) 1304 { 1305 CUMULATIVE_ARGS *ca = get_cumulative_args (cap); 1306 1307 msp430_evaluate_arg (cap, mode, type, named); 1308 1309 if (ca->reg_count && ca->mem_count) 1310 return ca->reg_count * UNITS_PER_WORD; 1311 1312 return 0; 1313 } 1314 1315 #undef TARGET_PASS_BY_REFERENCE 1316 #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference 1317 1318 static bool 1319 msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED, 1320 machine_mode mode, 1321 const_tree type, 1322 bool named ATTRIBUTE_UNUSED) 1323 { 1324 return (mode == BLKmode 1325 || (type && TREE_CODE (type) == RECORD_TYPE) 1326 || (type && TREE_CODE (type) == UNION_TYPE)); 1327 } 1328 1329 #undef TARGET_CALLEE_COPIES 1330 #define TARGET_CALLEE_COPIES msp430_callee_copies 1331 1332 static bool 1333 msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED, 1334 machine_mode mode ATTRIBUTE_UNUSED, 1335 const_tree type ATTRIBUTE_UNUSED, 1336 bool named ATTRIBUTE_UNUSED) 1337 { 1338 return true; 1339 } 1340 1341 #undef TARGET_FUNCTION_ARG_ADVANCE 1342 #define TARGET_FUNCTION_ARG_ADVANCE msp430_function_arg_advance 1343 1344 void 1345 msp430_function_arg_advance (cumulative_args_t cap, 1346 machine_mode mode, 1347 const_tree type, 1348 bool named) 1349 { 1350 CUMULATIVE_ARGS *ca = get_cumulative_args (cap); 1351 int i; 1352 1353 msp430_evaluate_arg (cap, mode, type, named); 1354 1355 if (ca->start_reg >= CA_FIRST_REG) 1356 for (i = 0; i < ca->reg_count; i ++) 1357 ca->reg_used [i + ca->start_reg - CA_FIRST_REG] = 1; 1358 1359 ca->special_p = 0; 1360 } 1361 1362 #undef TARGET_FUNCTION_ARG_BOUNDARY 1363 #define TARGET_FUNCTION_ARG_BOUNDARY msp430_function_arg_boundary 1364 1365 static unsigned int 1366 msp430_function_arg_boundary (machine_mode mode, const_tree type) 1367 { 1368 if (mode == BLKmode 1369 && int_size_in_bytes (type) > 1) 1370 return 16; 1371 if (GET_MODE_BITSIZE (mode) > 8) 1372 return 16; 1373 return 8; 1374 } 1375 1376 #undef TARGET_RETURN_IN_MEMORY 1377 #define TARGET_RETURN_IN_MEMORY msp430_return_in_memory 1378 1379 static bool 1380 msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED) 1381 { 1382 machine_mode mode = TYPE_MODE (ret_type); 1383 1384 if (mode == BLKmode 1385 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == RECORD_TYPE) 1386 || (fntype && TREE_CODE (TREE_TYPE (fntype)) == UNION_TYPE)) 1387 return true; 1388 1389 if (GET_MODE_SIZE (mode) > 8) 1390 return true; 1391 1392 return false; 1393 } 1394 1395 #undef TARGET_GET_RAW_ARG_MODE 1396 #define TARGET_GET_RAW_ARG_MODE msp430_get_raw_arg_mode 1397 1398 static machine_mode 1399 msp430_get_raw_arg_mode (int regno) 1400 { 1401 return (regno == ARG_POINTER_REGNUM) ? VOIDmode : Pmode; 1402 } 1403 1404 #undef TARGET_GET_RAW_RESULT_MODE 1405 #define TARGET_GET_RAW_RESULT_MODE msp430_get_raw_result_mode 1406 1407 static machine_mode 1408 msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED) 1409 { 1410 return Pmode; 1411 } 1412 1413 #undef TARGET_GIMPLIFY_VA_ARG_EXPR 1414 #define TARGET_GIMPLIFY_VA_ARG_EXPR msp430_gimplify_va_arg_expr 1415 1416 #include "gimplify.h" 1417 1418 static tree 1419 msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, 1420 gimple_seq *post_p) 1421 { 1422 tree addr, t, type_size, rounded_size, valist_tmp; 1423 unsigned HOST_WIDE_INT align, boundary; 1424 bool indirect; 1425 1426 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false); 1427 if (indirect) 1428 type = build_pointer_type (type); 1429 1430 align = PARM_BOUNDARY / BITS_PER_UNIT; 1431 boundary = targetm.calls.function_arg_boundary (TYPE_MODE (type), type); 1432 1433 /* When we align parameter on stack for caller, if the parameter 1434 alignment is beyond MAX_SUPPORTED_STACK_ALIGNMENT, it will be 1435 aligned at MAX_SUPPORTED_STACK_ALIGNMENT. We will match callee 1436 here with caller. */ 1437 if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT) 1438 boundary = MAX_SUPPORTED_STACK_ALIGNMENT; 1439 1440 boundary /= BITS_PER_UNIT; 1441 1442 /* Hoist the valist value into a temporary for the moment. */ 1443 valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL); 1444 1445 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually 1446 requires greater alignment, we must perform dynamic alignment. */ 1447 if (boundary > align 1448 && !integer_zerop (TYPE_SIZE (type))) 1449 { 1450 /* FIXME: This is where this function diverts from targhooks.c: 1451 std_gimplify_va_arg_expr(). It works, but I do not know why... */ 1452 if (! POINTER_TYPE_P (type)) 1453 { 1454 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 1455 fold_build_pointer_plus_hwi (valist_tmp, boundary - 1)); 1456 gimplify_and_add (t, pre_p); 1457 1458 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp, 1459 fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist), 1460 valist_tmp, 1461 build_int_cst (TREE_TYPE (valist), -boundary))); 1462 gimplify_and_add (t, pre_p); 1463 } 1464 } 1465 else 1466 boundary = align; 1467 1468 /* If the actual alignment is less than the alignment of the type, 1469 adjust the type accordingly so that we don't assume strict alignment 1470 when dereferencing the pointer. */ 1471 boundary *= BITS_PER_UNIT; 1472 if (boundary < TYPE_ALIGN (type)) 1473 { 1474 type = build_variant_type_copy (type); 1475 SET_TYPE_ALIGN (type, boundary); 1476 } 1477 1478 /* Compute the rounded size of the type. */ 1479 type_size = size_in_bytes (type); 1480 rounded_size = round_up (type_size, align); 1481 1482 /* Reduce rounded_size so it's sharable with the postqueue. */ 1483 gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); 1484 1485 /* Get AP. */ 1486 addr = valist_tmp; 1487 1488 /* Compute new value for AP. */ 1489 t = fold_build_pointer_plus (valist_tmp, rounded_size); 1490 t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t); 1491 gimplify_and_add (t, pre_p); 1492 1493 addr = fold_convert (build_pointer_type (type), addr); 1494 1495 if (indirect) 1496 addr = build_va_arg_indirect_ref (addr); 1497 1498 addr = build_va_arg_indirect_ref (addr); 1499 1500 return addr; 1501 } 1502 1503 #undef TARGET_LRA_P 1504 #define TARGET_LRA_P hook_bool_void_false 1505 1506 /* Addressing Modes */ 1507 1508 #undef TARGET_LEGITIMATE_ADDRESS_P 1509 #define TARGET_LEGITIMATE_ADDRESS_P msp430_legitimate_address_p 1510 1511 static bool 1512 reg_ok_for_addr (rtx r, bool strict) 1513 { 1514 int rn = REGNO (r); 1515 1516 if (strict && rn >= FIRST_PSEUDO_REGISTER) 1517 rn = reg_renumber [rn]; 1518 if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER) 1519 return true; 1520 if (!strict) 1521 return true; 1522 return false; 1523 } 1524 1525 bool 1526 msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, 1527 rtx x ATTRIBUTE_UNUSED, 1528 bool strict ATTRIBUTE_UNUSED) 1529 { 1530 switch (GET_CODE (x)) 1531 { 1532 case MEM: 1533 return false; 1534 1535 case PLUS: 1536 if (REG_P (XEXP (x, 0))) 1537 { 1538 if (GET_MODE (x) != GET_MODE (XEXP (x, 0))) 1539 return false; 1540 if (!reg_ok_for_addr (XEXP (x, 0), strict)) 1541 return false; 1542 switch (GET_CODE (XEXP (x, 1))) 1543 { 1544 case CONST: 1545 case SYMBOL_REF: 1546 case CONST_INT: 1547 return true; 1548 default: 1549 return false; 1550 } 1551 } 1552 return false; 1553 1554 case REG: 1555 if (!reg_ok_for_addr (x, strict)) 1556 return false; 1557 /* FALLTHRU */ 1558 case CONST: 1559 case SYMBOL_REF: 1560 case CONST_INT: 1561 return true; 1562 1563 default: 1564 return false; 1565 } 1566 } 1567 1568 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P 1569 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p 1570 1571 bool 1572 msp430_addr_space_legitimate_address_p (machine_mode mode, 1573 rtx x, 1574 bool strict, 1575 addr_space_t as ATTRIBUTE_UNUSED) 1576 { 1577 return msp430_legitimate_address_p (mode, x, strict); 1578 } 1579 1580 #undef TARGET_ASM_INTEGER 1581 #define TARGET_ASM_INTEGER msp430_asm_integer 1582 static bool 1583 msp430_asm_integer (rtx x, unsigned int size, int aligned_p) 1584 { 1585 int c = GET_CODE (x); 1586 1587 if (size == 3 && GET_MODE (x) == PSImode) 1588 size = 4; 1589 1590 switch (size) 1591 { 1592 case 4: 1593 if (c == SYMBOL_REF || c == CONST || c == LABEL_REF || c == CONST_INT 1594 || c == PLUS || c == MINUS) 1595 { 1596 fprintf (asm_out_file, "\t.long\t"); 1597 output_addr_const (asm_out_file, x); 1598 fputc ('\n', asm_out_file); 1599 return true; 1600 } 1601 break; 1602 } 1603 return default_assemble_integer (x, size, aligned_p); 1604 } 1605 1606 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA 1607 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA msp430_asm_output_addr_const_extra 1608 static bool 1609 msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x) 1610 { 1611 debug_rtx(x); 1612 return false; 1613 } 1614 1615 #undef TARGET_LEGITIMATE_CONSTANT_P 1616 #define TARGET_LEGITIMATE_CONSTANT_P msp430_legitimate_constant 1617 1618 static bool 1619 msp430_legitimate_constant (machine_mode mode, rtx x) 1620 { 1621 return ! CONST_INT_P (x) 1622 || mode != PSImode 1623 /* GCC does not know the width of the PSImode, so make 1624 sure that it does not try to use a constant value that 1625 is out of range. */ 1626 || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20)); 1627 } 1628 1629 1630 #undef TARGET_RTX_COSTS 1631 #define TARGET_RTX_COSTS msp430_rtx_costs 1632 1633 static bool msp430_rtx_costs (rtx x ATTRIBUTE_UNUSED, 1634 machine_mode mode, 1635 int outer_code ATTRIBUTE_UNUSED, 1636 int opno ATTRIBUTE_UNUSED, 1637 int * total, 1638 bool speed ATTRIBUTE_UNUSED) 1639 { 1640 int code = GET_CODE (x); 1641 1642 switch (code) 1643 { 1644 case SIGN_EXTEND: 1645 if (mode == SImode && outer_code == SET) 1646 { 1647 *total = COSTS_N_INSNS (4); 1648 return true; 1649 } 1650 break; 1651 case ASHIFT: 1652 case ASHIFTRT: 1653 case LSHIFTRT: 1654 if (!msp430x) 1655 { 1656 *total = COSTS_N_INSNS (100); 1657 return true; 1658 } 1659 break; 1660 } 1661 return false; 1662 } 1663 1664 /* Function Entry and Exit */ 1665 1666 /* The MSP430 call frame looks like this: 1667 1668 <higher addresses> 1669 +--------------------+ 1670 | | 1671 | Stack Arguments | 1672 | | 1673 +--------------------+ <-- "arg pointer" 1674 | | 1675 | PC from call | (2 bytes for 430, 4 for TARGET_LARGE) 1676 | | 1677 +--------------------+ 1678 | SR if this func has| 1679 | been called via an | 1680 | interrupt. | 1681 +--------------------+ <-- SP before prologue, also AP 1682 | | 1683 | Saved Regs | (2 bytes per reg for 430, 4 per for TARGET_LARGE) 1684 | | 1685 +--------------------+ <-- "frame pointer" 1686 | | 1687 | Locals | 1688 | | 1689 +--------------------+ 1690 | | 1691 | Outgoing Args | 1692 | | 1693 +--------------------+ <-- SP during function 1694 <lower addresses> 1695 1696 */ 1697 1698 /* We use this to wrap all emitted insns in the prologue, so they get 1699 the "frame-related" (/f) flag set. */ 1700 static rtx 1701 F (rtx x) 1702 { 1703 RTX_FRAME_RELATED_P (x) = 1; 1704 return x; 1705 } 1706 1707 /* This is the one spot that decides if a register is to be saved and 1708 restored in the prologue/epilogue. */ 1709 static bool 1710 msp430_preserve_reg_p (int regno) 1711 { 1712 /* PC, SP, SR, and the constant generator. */ 1713 if (regno <= 3) 1714 return false; 1715 1716 /* FIXME: add interrupt, EH, etc. */ 1717 if (crtl->calls_eh_return) 1718 return true; 1719 1720 /* Shouldn't be more than the above, but just in case... */ 1721 if (fixed_regs [regno]) 1722 return false; 1723 1724 /* Interrupt handlers save all registers they use, even 1725 ones which are call saved. If they call other functions 1726 then *every* register is saved. */ 1727 if (msp430_is_interrupt_func ()) 1728 return ! crtl->is_leaf || df_regs_ever_live_p (regno); 1729 1730 if (!call_used_regs [regno] 1731 && df_regs_ever_live_p (regno)) 1732 return true; 1733 1734 return false; 1735 } 1736 1737 /* Compute all the frame-related fields in our machine_function 1738 structure. */ 1739 static void 1740 msp430_compute_frame_info (void) 1741 { 1742 int i; 1743 1744 cfun->machine->computed = 1; 1745 cfun->machine->framesize_regs = 0; 1746 cfun->machine->framesize_locals = get_frame_size (); 1747 cfun->machine->framesize_outgoing = crtl->outgoing_args_size; 1748 1749 for (i = 0; i < ARG_POINTER_REGNUM; i ++) 1750 if (msp430_preserve_reg_p (i)) 1751 { 1752 cfun->machine->need_to_save [i] = 1; 1753 cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2); 1754 } 1755 else 1756 cfun->machine->need_to_save [i] = 0; 1757 1758 if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1) 1759 cfun->machine->framesize_locals ++; 1760 1761 cfun->machine->framesize = (cfun->machine->framesize_regs 1762 + cfun->machine->framesize_locals 1763 + cfun->machine->framesize_outgoing); 1764 } 1765 1766 /* Attribute Handling. */ 1767 1768 const char * const ATTR_INTR = "interrupt"; 1769 const char * const ATTR_WAKEUP = "wakeup"; 1770 const char * const ATTR_NAKED = "naked"; 1771 const char * const ATTR_REENT = "reentrant"; 1772 const char * const ATTR_CRIT = "critical"; 1773 const char * const ATTR_LOWER = "lower"; 1774 const char * const ATTR_UPPER = "upper"; 1775 const char * const ATTR_EITHER = "either"; 1776 const char * const ATTR_NOINIT = "noinit"; 1777 const char * const ATTR_PERSIST = "persistent"; 1778 1779 static inline bool 1780 has_attr (const char * attr, tree decl) 1781 { 1782 if (decl == NULL_TREE) 1783 return false; 1784 return lookup_attribute (attr, DECL_ATTRIBUTES (decl)) != NULL_TREE; 1785 } 1786 1787 static bool 1788 is_interrupt_func (tree decl = current_function_decl) 1789 { 1790 return has_attr (ATTR_INTR, decl); 1791 } 1792 1793 /* Returns true if the current function has the "interrupt" attribute. */ 1794 1795 bool 1796 msp430_is_interrupt_func (void) 1797 { 1798 return is_interrupt_func (current_function_decl); 1799 } 1800 1801 static bool 1802 is_wakeup_func (tree decl = current_function_decl) 1803 { 1804 return is_interrupt_func (decl) && has_attr (ATTR_WAKEUP, decl); 1805 } 1806 1807 static inline bool 1808 is_naked_func (tree decl = current_function_decl) 1809 { 1810 return has_attr (ATTR_NAKED, decl); 1811 } 1812 1813 static inline bool 1814 is_reentrant_func (tree decl = current_function_decl) 1815 { 1816 return has_attr (ATTR_REENT, decl); 1817 } 1818 1819 static inline bool 1820 is_critical_func (tree decl = current_function_decl) 1821 { 1822 return has_attr (ATTR_CRIT, decl); 1823 } 1824 1825 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS 1826 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args 1827 1828 static bool 1829 msp430_allocate_stack_slots_for_args (void) 1830 { 1831 /* Naked functions should not allocate stack slots for arguments. */ 1832 return ! is_naked_func (); 1833 } 1834 1835 /* Verify MSP430 specific attributes. */ 1836 #define TREE_NAME_EQ(NAME, STR) (strcmp (IDENTIFIER_POINTER (NAME), (STR)) == 0) 1837 1838 static tree 1839 msp430_attr (tree * node, 1840 tree name, 1841 tree args, 1842 int flags ATTRIBUTE_UNUSED, 1843 bool * no_add_attrs) 1844 { 1845 gcc_assert (DECL_P (* node)); 1846 1847 if (args != NULL) 1848 { 1849 /* Only the interrupt attribute takes an argument. */ 1850 gcc_assert (TREE_NAME_EQ (name, ATTR_INTR)); 1851 1852 tree value = TREE_VALUE (args); 1853 1854 switch (TREE_CODE (value)) 1855 { 1856 case STRING_CST: 1857 if ( strcmp (TREE_STRING_POINTER (value), "reset") 1858 && strcmp (TREE_STRING_POINTER (value), "nmi") 1859 && strcmp (TREE_STRING_POINTER (value), "watchdog")) 1860 /* Allow the attribute to be added - the linker script 1861 being used may still recognise this name. */ 1862 warning (OPT_Wattributes, 1863 "unrecognized interrupt vector argument of %qE attribute", 1864 name); 1865 break; 1866 1867 case INTEGER_CST: 1868 if (wi::gtu_p (value, 63)) 1869 /* Allow the attribute to be added - the linker script 1870 being used may still recognise this value. */ 1871 warning (OPT_Wattributes, 1872 "numeric argument of %qE attribute must be in range 0..63", 1873 name); 1874 break; 1875 1876 default: 1877 warning (OPT_Wattributes, 1878 "argument of %qE attribute is not a string constant or number", 1879 name); 1880 *no_add_attrs = true; 1881 break; 1882 } 1883 } 1884 1885 const char * message = NULL; 1886 1887 if (TREE_CODE (* node) != FUNCTION_DECL) 1888 { 1889 message = "%qE attribute only applies to functions"; 1890 } 1891 else if (TREE_NAME_EQ (name, ATTR_INTR)) 1892 { 1893 if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE 1894 && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node)))) 1895 message = "interrupt handlers must be void"; 1896 1897 if (! TREE_PUBLIC (* node)) 1898 message = "interrupt handlers cannot be static"; 1899 } 1900 else if (TREE_NAME_EQ (name, ATTR_REENT)) 1901 { 1902 if (is_naked_func (* node)) 1903 message = "naked functions cannot be reentrant"; 1904 else if (is_critical_func (* node)) 1905 message = "critical functions cannot be reentrant"; 1906 } 1907 else if (TREE_NAME_EQ (name, ATTR_CRIT)) 1908 { 1909 if (is_naked_func (* node)) 1910 message = "naked functions cannot be critical"; 1911 else if (is_reentrant_func (* node)) 1912 message = "reentrant functions cannot be critical"; 1913 } 1914 else if (TREE_NAME_EQ (name, ATTR_NAKED)) 1915 { 1916 if (is_critical_func (* node)) 1917 message = "critical functions cannot be naked"; 1918 else if (is_reentrant_func (* node)) 1919 message = "reentrant functions cannot be naked"; 1920 } 1921 1922 if (message) 1923 { 1924 warning (OPT_Wattributes, message, name); 1925 * no_add_attrs = true; 1926 } 1927 1928 return NULL_TREE; 1929 } 1930 1931 static tree 1932 msp430_section_attr (tree * node, 1933 tree name, 1934 tree args, 1935 int flags ATTRIBUTE_UNUSED, 1936 bool * no_add_attrs ATTRIBUTE_UNUSED) 1937 { 1938 gcc_assert (DECL_P (* node)); 1939 gcc_assert (args == NULL); 1940 1941 const char * message = NULL; 1942 1943 if (TREE_NAME_EQ (name, ATTR_UPPER)) 1944 { 1945 if (has_attr (ATTR_LOWER, * node)) 1946 message = "already marked with 'lower' attribute"; 1947 else if (has_attr (ATTR_EITHER, * node)) 1948 message = "already marked with 'either' attribute"; 1949 else if (! msp430x) 1950 message = "upper attribute needs a 430X cpu"; 1951 } 1952 else if (TREE_NAME_EQ (name, ATTR_LOWER)) 1953 { 1954 if (has_attr (ATTR_UPPER, * node)) 1955 message = "already marked with 'upper' attribute"; 1956 else if (has_attr (ATTR_EITHER, * node)) 1957 message = "already marked with 'either' attribute"; 1958 } 1959 else 1960 { 1961 gcc_assert (TREE_NAME_EQ (name, ATTR_EITHER)); 1962 1963 if (has_attr (ATTR_LOWER, * node)) 1964 message = "already marked with 'lower' attribute"; 1965 else if (has_attr (ATTR_UPPER, * node)) 1966 message = "already marked with 'upper' attribute"; 1967 } 1968 1969 if (message) 1970 { 1971 warning (OPT_Wattributes, message, name); 1972 * no_add_attrs = true; 1973 } 1974 1975 return NULL_TREE; 1976 } 1977 1978 static tree 1979 msp430_data_attr (tree * node, 1980 tree name, 1981 tree args, 1982 int flags ATTRIBUTE_UNUSED, 1983 bool * no_add_attrs ATTRIBUTE_UNUSED) 1984 { 1985 const char * message = NULL; 1986 1987 gcc_assert (DECL_P (* node)); 1988 gcc_assert (args == NULL); 1989 1990 if (TREE_CODE (* node) != VAR_DECL) 1991 message = "%qE attribute only applies to variables"; 1992 1993 if (DECL_SECTION_NAME (* node)) 1994 message = "%qE attribute cannot be applied to variables with specific sections"; 1995 1996 /* If this var is thought to be common, then change this. Common variables 1997 are assigned to sections before the backend has a chance to process them. */ 1998 if (DECL_COMMON (* node)) 1999 DECL_COMMON (* node) = 0; 2000 2001 if (message) 2002 { 2003 warning (OPT_Wattributes, message, name); 2004 * no_add_attrs = true; 2005 } 2006 2007 return NULL_TREE; 2008 } 2009 2010 2011 #undef TARGET_ATTRIBUTE_TABLE 2012 #define TARGET_ATTRIBUTE_TABLE msp430_attribute_table 2013 2014 /* Table of MSP430-specific attributes. */ 2015 const struct attribute_spec msp430_attribute_table[] = 2016 { 2017 /* Name min_num_args type_req, affects_type_identity 2018 max_num_args, fn_type_req 2019 decl_req handler. */ 2020 { ATTR_INTR, 0, 1, true, false, false, msp430_attr, false }, 2021 { ATTR_NAKED, 0, 0, true, false, false, msp430_attr, false }, 2022 { ATTR_REENT, 0, 0, true, false, false, msp430_attr, false }, 2023 { ATTR_CRIT, 0, 0, true, false, false, msp430_attr, false }, 2024 { ATTR_WAKEUP, 0, 0, true, false, false, msp430_attr, false }, 2025 2026 { ATTR_LOWER, 0, 0, true, false, false, msp430_section_attr, false }, 2027 { ATTR_UPPER, 0, 0, true, false, false, msp430_section_attr, false }, 2028 { ATTR_EITHER, 0, 0, true, false, false, msp430_section_attr, false }, 2029 2030 { ATTR_NOINIT, 0, 0, true, false, false, msp430_data_attr, false }, 2031 { ATTR_PERSIST, 0, 0, true, false, false, msp430_data_attr, false }, 2032 2033 { NULL, 0, 0, false, false, false, NULL, false } 2034 }; 2035 2036 #undef TARGET_ASM_FUNCTION_PROLOGUE 2037 #define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function 2038 2039 static void 2040 msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED) 2041 { 2042 int r, n; 2043 2044 fprintf (outfile, "; start of function\n"); 2045 2046 if (DECL_ATTRIBUTES (current_function_decl) != NULL_TREE) 2047 { 2048 fprintf (outfile, "; attributes: "); 2049 if (is_naked_func ()) 2050 fprintf (outfile, "naked "); 2051 if (msp430_is_interrupt_func ()) 2052 fprintf (outfile, "interrupt "); 2053 if (is_reentrant_func ()) 2054 fprintf (outfile, "reentrant "); 2055 if (is_critical_func ()) 2056 fprintf (outfile, "critical "); 2057 if (is_wakeup_func ()) 2058 fprintf (outfile, "wakeup "); 2059 fprintf (outfile, "\n"); 2060 } 2061 2062 fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs); 2063 fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals); 2064 fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing); 2065 fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize); 2066 fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM)); 2067 fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM)); 2068 2069 n = 0; 2070 fprintf (outfile, "; saved regs:"); 2071 for (r = 0; r < ARG_POINTER_REGNUM; r++) 2072 if (cfun->machine->need_to_save [r]) 2073 { 2074 fprintf (outfile, " %s", reg_names [r]); 2075 n = 1; 2076 } 2077 if (n == 0) 2078 fprintf (outfile, "(none)"); 2079 fprintf (outfile, "\n"); 2080 } 2081 2082 /* Common code to change the stack pointer. */ 2083 static void 2084 increment_stack (HOST_WIDE_INT amount) 2085 { 2086 rtx inc; 2087 rtx sp = stack_pointer_rtx; 2088 2089 if (amount == 0) 2090 return; 2091 2092 if (amount < 0) 2093 { 2094 inc = GEN_INT (- amount); 2095 if (TARGET_LARGE) 2096 F (emit_insn (gen_subpsi3 (sp, sp, inc))); 2097 else 2098 F (emit_insn (gen_subhi3 (sp, sp, inc))); 2099 } 2100 else 2101 { 2102 inc = GEN_INT (amount); 2103 if (TARGET_LARGE) 2104 emit_insn (gen_addpsi3 (sp, sp, inc)); 2105 else 2106 emit_insn (gen_addhi3 (sp, sp, inc)); 2107 } 2108 } 2109 2110 void 2111 msp430_start_function (FILE *file, const char *name, tree decl) 2112 { 2113 tree int_attr; 2114 2115 int_attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl)); 2116 if (int_attr != NULL_TREE) 2117 { 2118 tree intr_vector = TREE_VALUE (int_attr); 2119 2120 if (intr_vector != NULL_TREE) 2121 { 2122 char buf[101]; 2123 2124 /* Interrupt vector sections should be unique, but use of weak 2125 functions implies multiple definitions. */ 2126 if (DECL_WEAK (decl)) 2127 { 2128 error ("argument to interrupt attribute is unsupported for weak functions"); 2129 } 2130 2131 intr_vector = TREE_VALUE (intr_vector); 2132 2133 /* The interrupt attribute has a vector value. Turn this into a 2134 section name, switch to that section and put the address of 2135 the current function into that vector slot. Note msp430_attr() 2136 has already verified the vector name for us. */ 2137 if (TREE_CODE (intr_vector) == STRING_CST) 2138 sprintf (buf, "__interrupt_vector_%.80s", 2139 TREE_STRING_POINTER (intr_vector)); 2140 else /* TREE_CODE (intr_vector) == INTEGER_CST */ 2141 sprintf (buf, "__interrupt_vector_%u", 2142 (unsigned int) TREE_INT_CST_LOW (intr_vector)); 2143 2144 switch_to_section (get_section (buf, SECTION_CODE, decl)); 2145 fputs ("\t.word\t", file); 2146 assemble_name (file, name); 2147 fputc ('\n', file); 2148 fputc ('\t', file); 2149 } 2150 } 2151 2152 switch_to_section (function_section (decl)); 2153 ASM_OUTPUT_TYPE_DIRECTIVE(file, name, "function"); 2154 ASM_OUTPUT_FUNCTION_LABEL (file, name, decl); 2155 } 2156 2157 static const char * const lower_prefix = ".lower"; 2158 static const char * const upper_prefix = ".upper"; 2159 static const char * const either_prefix = ".either"; 2160 2161 /* Generate a prefix for a section name, based upon 2162 the region into which the object should be placed. */ 2163 2164 static const char * 2165 gen_prefix (tree decl) 2166 { 2167 if (DECL_ONE_ONLY (decl)) 2168 return NULL; 2169 2170 /* If the user has specified a particular section then do not use any prefix. */ 2171 if (has_attr ("section", decl)) 2172 return NULL; 2173 2174 /* If the object has __attribute__((lower)) then use the ".lower." prefix. */ 2175 if (has_attr (ATTR_LOWER, decl)) 2176 return lower_prefix; 2177 2178 /* If we are compiling for the MSP430 then we do not support the upper region. */ 2179 if (! msp430x) 2180 return NULL; 2181 2182 if (has_attr (ATTR_UPPER, decl)) 2183 return upper_prefix; 2184 2185 if (has_attr (ATTR_EITHER, decl)) 2186 return either_prefix; 2187 2188 if (TREE_CODE (decl) == FUNCTION_DECL) 2189 { 2190 if (msp430_code_region == MSP430_REGION_LOWER) 2191 return lower_prefix; 2192 2193 if (msp430_code_region == MSP430_REGION_UPPER) 2194 return upper_prefix; 2195 2196 if (msp430_code_region == MSP430_REGION_EITHER) 2197 return either_prefix; 2198 } 2199 else 2200 { 2201 if (msp430_data_region == MSP430_REGION_LOWER) 2202 return lower_prefix; 2203 2204 if (msp430_data_region == MSP430_REGION_UPPER) 2205 return upper_prefix; 2206 2207 if (msp430_data_region == MSP430_REGION_EITHER) 2208 return either_prefix; 2209 } 2210 2211 return NULL; 2212 } 2213 2214 static section * noinit_section; 2215 static section * persist_section; 2216 2217 #undef TARGET_ASM_INIT_SECTIONS 2218 #define TARGET_ASM_INIT_SECTIONS msp430_init_sections 2219 2220 static void 2221 msp430_init_sections (void) 2222 { 2223 noinit_section = get_unnamed_section (0, output_section_asm_op, ".section .noinit,\"aw\""); 2224 persist_section = get_unnamed_section (0, output_section_asm_op, ".section .persistent,\"aw\""); 2225 } 2226 2227 #undef TARGET_ASM_SELECT_SECTION 2228 #define TARGET_ASM_SELECT_SECTION msp430_select_section 2229 2230 static section * 2231 msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) 2232 { 2233 gcc_assert (decl != NULL_TREE); 2234 2235 if (TREE_CODE (decl) == STRING_CST 2236 || TREE_CODE (decl) == CONSTRUCTOR 2237 || TREE_CODE (decl) == INTEGER_CST 2238 || TREE_CODE (decl) == VECTOR_CST 2239 || TREE_CODE (decl) == COMPLEX_CST) 2240 return default_select_section (decl, reloc, align); 2241 2242 /* In large mode we must make sure that interrupt handlers are put into 2243 low memory as the vector table only accepts 16-bit addresses. */ 2244 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl)) 2245 return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl); 2246 2247 const char * prefix = gen_prefix (decl); 2248 if (prefix == NULL) 2249 { 2250 if (TREE_CODE (decl) == FUNCTION_DECL) 2251 return text_section; 2252 else if (has_attr (ATTR_NOINIT, decl)) 2253 return noinit_section; 2254 else if (has_attr (ATTR_PERSIST, decl)) 2255 return persist_section; 2256 else 2257 return default_select_section (decl, reloc, align); 2258 } 2259 2260 const char * sec; 2261 switch (categorize_decl_for_section (decl, reloc)) 2262 { 2263 case SECCAT_TEXT: sec = ".text"; break; 2264 case SECCAT_DATA: sec = ".data"; break; 2265 case SECCAT_BSS: sec = ".bss"; break; 2266 case SECCAT_RODATA: sec = ".rodata"; break; 2267 2268 case SECCAT_RODATA_MERGE_STR: 2269 case SECCAT_RODATA_MERGE_STR_INIT: 2270 case SECCAT_RODATA_MERGE_CONST: 2271 case SECCAT_SRODATA: 2272 case SECCAT_DATA_REL: 2273 case SECCAT_DATA_REL_LOCAL: 2274 case SECCAT_DATA_REL_RO: 2275 case SECCAT_DATA_REL_RO_LOCAL: 2276 case SECCAT_SDATA: 2277 case SECCAT_SBSS: 2278 case SECCAT_TDATA: 2279 case SECCAT_TBSS: 2280 return default_select_section (decl, reloc, align); 2281 2282 default: 2283 gcc_unreachable (); 2284 } 2285 2286 const char * dec_name = DECL_SECTION_NAME (decl); 2287 char * name = ACONCAT ((prefix, sec, dec_name, NULL)); 2288 2289 return get_named_section (decl, name, 0); 2290 } 2291 2292 #undef TARGET_ASM_FUNCTION_SECTION 2293 #define TARGET_ASM_FUNCTION_SECTION msp430_function_section 2294 2295 static section * 2296 msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit) 2297 { 2298 const char * name; 2299 2300 gcc_assert (DECL_SECTION_NAME (decl) != NULL); 2301 name = DECL_SECTION_NAME (decl); 2302 2303 const char * prefix = gen_prefix (decl); 2304 if (prefix == NULL 2305 || strncmp (name, prefix, strlen (prefix)) == 0) 2306 return default_function_section (decl, freq, startup, exit); 2307 2308 name = ACONCAT ((prefix, name, NULL)); 2309 return get_named_section (decl, name, 0); 2310 } 2311 2312 #undef TARGET_SECTION_TYPE_FLAGS 2313 #define TARGET_SECTION_TYPE_FLAGS msp430_section_type_flags 2314 2315 unsigned int 2316 msp430_section_type_flags (tree decl, const char * name, int reloc) 2317 { 2318 if (strncmp (name, lower_prefix, strlen (lower_prefix)) == 0) 2319 name += strlen (lower_prefix); 2320 else if (strncmp (name, upper_prefix, strlen (upper_prefix)) == 0) 2321 name += strlen (upper_prefix); 2322 else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0) 2323 name += strlen (either_prefix); 2324 else if (strcmp (name, ".noinit") == 0) 2325 return SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE; 2326 else if (strcmp (name, ".persistent") == 0) 2327 return SECTION_WRITE | SECTION_NOTYPE; 2328 2329 return default_section_type_flags (decl, name, reloc); 2330 } 2331 2332 #undef TARGET_ASM_UNIQUE_SECTION 2333 #define TARGET_ASM_UNIQUE_SECTION msp430_unique_section 2334 2335 static void 2336 msp430_unique_section (tree decl, int reloc) 2337 { 2338 gcc_assert (decl != NULL_TREE); 2339 2340 /* In large mode we must make sure that interrupt handlers are put into 2341 low memory as the vector table only accepts 16-bit addresses. */ 2342 if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl)) 2343 { 2344 set_decl_section_name (decl, ".lowtext"); 2345 return; 2346 } 2347 2348 default_unique_section (decl, reloc); 2349 2350 const char * prefix; 2351 2352 if ( TREE_CODE (decl) == STRING_CST 2353 || TREE_CODE (decl) == CONSTRUCTOR 2354 || TREE_CODE (decl) == INTEGER_CST 2355 || TREE_CODE (decl) == VECTOR_CST 2356 || TREE_CODE (decl) == COMPLEX_CST 2357 || (prefix = gen_prefix (decl)) == NULL 2358 ) 2359 return; 2360 2361 const char * dec_name = DECL_SECTION_NAME (decl); 2362 char * name = ACONCAT ((prefix, dec_name, NULL)); 2363 2364 set_decl_section_name (decl, name); 2365 } 2366 2367 /* Emit a declaration of a common symbol. 2368 If a data region is in use then put the symbol into the 2369 equivalent .bss section instead. */ 2370 2371 void 2372 msp430_output_aligned_decl_common (FILE * stream, 2373 const tree decl, 2374 const char * name, 2375 unsigned HOST_WIDE_INT size, 2376 unsigned int align) 2377 { 2378 if (msp430_data_region == MSP430_REGION_ANY) 2379 { 2380 fprintf (stream, COMMON_ASM_OP); 2381 assemble_name (stream, name); 2382 fprintf (stream, "," HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", 2383 size, align / BITS_PER_UNIT); 2384 } 2385 else 2386 { 2387 section * sec; 2388 2389 if (decl) 2390 sec = msp430_select_section (decl, 0, align); 2391 else 2392 switch (msp430_data_region) 2393 { 2394 case MSP430_REGION_UPPER: sec = get_named_section (NULL, ".upper.bss", 0); break; 2395 case MSP430_REGION_LOWER: sec = get_named_section (NULL, ".lower.bss", 0); break; 2396 case MSP430_REGION_EITHER: sec = get_named_section (NULL, ".either.bss", 0); break; 2397 default: 2398 gcc_unreachable (); 2399 } 2400 gcc_assert (sec != NULL); 2401 2402 switch_to_section (sec); 2403 ASM_OUTPUT_ALIGN (stream, floor_log2 (align / BITS_PER_UNIT)); 2404 targetm.asm_out.globalize_label (stream, name); 2405 ASM_WEAKEN_LABEL (stream, name); 2406 ASM_OUTPUT_LABEL (stream, name); 2407 ASM_OUTPUT_SKIP (stream, size ? size : 1); 2408 } 2409 } 2410 2411 bool 2412 msp430_do_not_relax_short_jumps (void) 2413 { 2414 /* When placing code into "either" low or high memory we do not want the linker 2415 to grow the size of sections, which it can do if it is encounters a branch to 2416 a label that is too far away. So we tell the cbranch patterns to avoid using 2417 short jumps when there is a chance that the instructions will end up in a low 2418 section. */ 2419 return 2420 msp430_code_region == MSP430_REGION_EITHER 2421 || msp430_code_region == MSP430_REGION_LOWER 2422 || has_attr (ATTR_EITHER, current_function_decl) 2423 || has_attr (ATTR_LOWER, current_function_decl); 2424 } 2425 2426 enum msp430_builtin 2427 { 2428 MSP430_BUILTIN_BIC_SR, 2429 MSP430_BUILTIN_BIS_SR, 2430 MSP430_BUILTIN_DELAY_CYCLES, 2431 MSP430_BUILTIN_max 2432 }; 2433 2434 static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max]; 2435 2436 static void 2437 msp430_init_builtins (void) 2438 { 2439 tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL); 2440 tree void_ftype_longlong = build_function_type_list (void_type_node, long_long_integer_type_node, NULL); 2441 2442 msp430_builtins[MSP430_BUILTIN_BIC_SR] = 2443 add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int, 2444 MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE); 2445 2446 msp430_builtins[MSP430_BUILTIN_BIS_SR] = 2447 add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int, 2448 MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE); 2449 2450 msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] = 2451 add_builtin_function ( "__delay_cycles", void_ftype_longlong, 2452 MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL, NULL_TREE); 2453 } 2454 2455 static tree 2456 msp430_builtin_decl (unsigned code, bool initialize ATTRIBUTE_UNUSED) 2457 { 2458 switch (code) 2459 { 2460 case MSP430_BUILTIN_BIC_SR: 2461 case MSP430_BUILTIN_BIS_SR: 2462 case MSP430_BUILTIN_DELAY_CYCLES: 2463 return msp430_builtins[code]; 2464 default: 2465 return error_mark_node; 2466 } 2467 } 2468 2469 /* These constants are really register reads, which are faster than 2470 regular constants. */ 2471 static int 2472 cg_magic_constant (HOST_WIDE_INT c) 2473 { 2474 switch (c) 2475 { 2476 case 0xffff: 2477 case -1: 2478 case 0: 2479 case 1: 2480 case 2: 2481 case 4: 2482 case 8: 2483 return 1; 2484 default: 2485 return 0; 2486 } 2487 } 2488 2489 static rtx 2490 msp430_expand_delay_cycles (rtx arg) 2491 { 2492 HOST_WIDE_INT i, c, n; 2493 /* extra cycles for MSP430X instructions */ 2494 #define CYCX(M,X) (msp430x ? (X) : (M)) 2495 2496 if (GET_CODE (arg) != CONST_INT) 2497 { 2498 error ("__delay_cycles() only takes constant arguments"); 2499 return NULL_RTX; 2500 } 2501 2502 c = INTVAL (arg); 2503 2504 if (HOST_BITS_PER_WIDE_INT > 32) 2505 { 2506 if (c < 0) 2507 { 2508 error ("__delay_cycles only takes non-negative cycle counts"); 2509 return NULL_RTX; 2510 } 2511 } 2512 2513 emit_insn (gen_delay_cycles_start (arg)); 2514 2515 /* For 32-bit loops, there's 13(16) + 5(min(x,0x10000) + 6x cycles. */ 2516 if (c > 3 * 0xffff + CYCX (7, 10)) 2517 { 2518 n = c; 2519 /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */ 2520 if (c >= 0x10000 * 7 + CYCX (14, 16)) 2521 { 2522 i = 0x10000; 2523 c -= CYCX (14, 16) + 7 * 0x10000; 2524 i += c / 4; 2525 c %= 4; 2526 if ((unsigned long long) i > 0xffffffffULL) 2527 { 2528 error ("__delay_cycles is limited to 32-bit loop counts"); 2529 return NULL_RTX; 2530 } 2531 } 2532 else 2533 { 2534 i = (c - CYCX (14, 16)) / 7; 2535 c -= CYCX (14, 16) + i * 7; 2536 } 2537 2538 if (cg_magic_constant (i & 0xffff)) 2539 c ++; 2540 if (cg_magic_constant ((i >> 16) & 0xffff)) 2541 c ++; 2542 2543 if (msp430x) 2544 emit_insn (gen_delay_cycles_32x (GEN_INT (i), GEN_INT (n - c))); 2545 else 2546 emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c))); 2547 } 2548 2549 /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */ 2550 if (c > 12) 2551 { 2552 n = c; 2553 i = (c - CYCX (7, 10)) / 3; 2554 c -= CYCX (7, 10) + i * 3; 2555 2556 if (cg_magic_constant (i)) 2557 c ++; 2558 2559 if (msp430x) 2560 emit_insn (gen_delay_cycles_16x (GEN_INT (i), GEN_INT (n - c))); 2561 else 2562 emit_insn (gen_delay_cycles_16 (GEN_INT (i), GEN_INT (n - c))); 2563 } 2564 2565 while (c > 1) 2566 { 2567 emit_insn (gen_delay_cycles_2 ()); 2568 c -= 2; 2569 } 2570 2571 if (c) 2572 { 2573 emit_insn (gen_delay_cycles_1 ()); 2574 c -= 1; 2575 } 2576 2577 emit_insn (gen_delay_cycles_end (arg)); 2578 2579 return NULL_RTX; 2580 } 2581 2582 static rtx 2583 msp430_expand_builtin (tree exp, 2584 rtx target ATTRIBUTE_UNUSED, 2585 rtx subtarget ATTRIBUTE_UNUSED, 2586 machine_mode mode ATTRIBUTE_UNUSED, 2587 int ignore ATTRIBUTE_UNUSED) 2588 { 2589 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); 2590 unsigned int fcode = DECL_FUNCTION_CODE (fndecl); 2591 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0)); 2592 2593 if (fcode == MSP430_BUILTIN_DELAY_CYCLES) 2594 return msp430_expand_delay_cycles (arg1); 2595 2596 if (! msp430_is_interrupt_func ()) 2597 { 2598 error ("MSP430 builtin functions only work inside interrupt handlers"); 2599 return NULL_RTX; 2600 } 2601 2602 if (! REG_P (arg1) && ! CONSTANT_P (arg1)) 2603 arg1 = force_reg (mode, arg1); 2604 2605 switch (fcode) 2606 { 2607 case MSP430_BUILTIN_BIC_SR: emit_insn (gen_bic_SR (arg1)); break; 2608 case MSP430_BUILTIN_BIS_SR: emit_insn (gen_bis_SR (arg1)); break; 2609 default: 2610 internal_error ("bad builtin code"); 2611 break; 2612 } 2613 return NULL_RTX; 2614 } 2615 2616 #undef TARGET_INIT_BUILTINS 2617 #define TARGET_INIT_BUILTINS msp430_init_builtins 2618 2619 #undef TARGET_EXPAND_BUILTIN 2620 #define TARGET_EXPAND_BUILTIN msp430_expand_builtin 2621 2622 #undef TARGET_BUILTIN_DECL 2623 #define TARGET_BUILTIN_DECL msp430_builtin_decl 2624 2625 void 2626 msp430_expand_prologue (void) 2627 { 2628 int i, j; 2629 int fs; 2630 /* Always use stack_pointer_rtx instead of calling 2631 rtx_gen_REG ourselves. Code elsewhere in GCC assumes 2632 that there is a single rtx representing the stack pointer, 2633 namely stack_pointer_rtx, and uses == to recognize it. */ 2634 rtx sp = stack_pointer_rtx; 2635 rtx p; 2636 2637 if (is_naked_func ()) 2638 { 2639 /* We must generate some RTX as thread_prologue_and_epilogue_insns() 2640 examines the output of the gen_prologue() function. */ 2641 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0))); 2642 return; 2643 } 2644 2645 emit_insn (gen_prologue_start_marker ()); 2646 2647 if (is_critical_func ()) 2648 { 2649 emit_insn (gen_push_intr_state ()); 2650 emit_insn (gen_disable_interrupts ()); 2651 } 2652 else if (is_reentrant_func ()) 2653 emit_insn (gen_disable_interrupts ()); 2654 2655 if (!cfun->machine->computed) 2656 msp430_compute_frame_info (); 2657 2658 if (flag_stack_usage_info) 2659 current_function_static_stack_size = cfun->machine->framesize; 2660 2661 if (crtl->args.pretend_args_size) 2662 { 2663 rtx note; 2664 2665 gcc_assert (crtl->args.pretend_args_size == 2); 2666 2667 p = emit_insn (gen_grow_and_swap ()); 2668 2669 /* Document the stack decrement... */ 2670 note = F (gen_rtx_SET (stack_pointer_rtx, 2671 gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2)))); 2672 add_reg_note (p, REG_FRAME_RELATED_EXPR, note); 2673 2674 /* ...and the establishment of a new location for the return address. */ 2675 note = F (gen_rtx_SET (gen_rtx_MEM (Pmode, 2676 gen_rtx_PLUS (Pmode, 2677 stack_pointer_rtx, 2678 GEN_INT (-2))), 2679 pc_rtx)); 2680 add_reg_note (p, REG_CFA_OFFSET, note); 2681 F (p); 2682 } 2683 2684 for (i = 15; i >= 4; i--) 2685 if (cfun->machine->need_to_save [i]) 2686 { 2687 int seq, count; 2688 rtx note; 2689 2690 for (seq = i - 1; seq >= 4 && cfun->machine->need_to_save[seq]; seq --) 2691 ; 2692 count = i - seq; 2693 2694 if (msp430x) 2695 { 2696 /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */ 2697 p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i), 2698 GEN_INT (count)))); 2699 2700 note = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (count + 1)); 2701 2702 XVECEXP (note, 0, 0) 2703 = F (gen_rtx_SET (stack_pointer_rtx, 2704 gen_rtx_PLUS (Pmode, 2705 stack_pointer_rtx, 2706 GEN_INT (count * (TARGET_LARGE ? -4 : -2))))); 2707 2708 /* *sp-- = R[i-j] */ 2709 /* sp+N R10 2710 ... 2711 sp R4 */ 2712 for (j = 0; j < count; j ++) 2713 { 2714 rtx addr; 2715 int ofs = (count - j - 1) * (TARGET_LARGE ? 4 : 2); 2716 2717 if (ofs) 2718 addr = gen_rtx_PLUS (Pmode, sp, GEN_INT (ofs)); 2719 else 2720 addr = stack_pointer_rtx; 2721 2722 XVECEXP (note, 0, j + 1) = 2723 F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr), 2724 gen_rtx_REG (Pmode, i - j)) ); 2725 } 2726 2727 add_reg_note (p, REG_FRAME_RELATED_EXPR, note); 2728 i -= count - 1; 2729 } 2730 else 2731 F (emit_insn (gen_push (gen_rtx_REG (Pmode, i)))); 2732 } 2733 2734 if (frame_pointer_needed) 2735 F (emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM), sp)); 2736 2737 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; 2738 2739 increment_stack (- fs); 2740 2741 emit_insn (gen_prologue_end_marker ()); 2742 } 2743 2744 void 2745 msp430_expand_epilogue (int is_eh) 2746 { 2747 int i; 2748 int fs; 2749 int helper_n = 0; 2750 2751 if (is_naked_func ()) 2752 { 2753 /* We must generate some RTX as thread_prologue_and_epilogue_insns() 2754 examines the output of the gen_epilogue() function. */ 2755 emit_insn (gen_rtx_CLOBBER (VOIDmode, GEN_INT (0))); 2756 return; 2757 } 2758 2759 if (cfun->machine->need_to_save [10]) 2760 { 2761 /* Check for a helper function. */ 2762 helper_n = 7; /* For when the loop below never sees a match. */ 2763 for (i = 9; i >= 4; i--) 2764 if (!cfun->machine->need_to_save [i]) 2765 { 2766 helper_n = 10 - i; 2767 for (; i >= 4; i--) 2768 if (cfun->machine->need_to_save [i]) 2769 { 2770 helper_n = 0; 2771 break; 2772 } 2773 break; 2774 } 2775 } 2776 2777 emit_insn (gen_epilogue_start_marker ()); 2778 2779 if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), "main") == 0) 2780 emit_insn (gen_msp430_refsym_need_exit ()); 2781 2782 if (is_wakeup_func ()) 2783 /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the 2784 status register current residing on the stack. When this function 2785 executes its RETI instruction the SR will be updated with this saved 2786 value, thus ensuring that the processor is woken up from any low power 2787 state in which it may be residing. */ 2788 emit_insn (gen_bic_SR (GEN_INT (0xf0))); 2789 2790 fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; 2791 2792 increment_stack (fs); 2793 2794 if (is_eh) 2795 { 2796 /* We need to add the right "SP" register save just after the 2797 regular ones, so that when we pop it off we're in the EH 2798 return frame, not this one. This overwrites our own return 2799 address, but we're not going to be returning anyway. */ 2800 rtx r12 = gen_rtx_REG (Pmode, 12); 2801 rtx (*addPmode)(rtx, rtx, rtx) = TARGET_LARGE ? gen_addpsi3 : gen_addhi3; 2802 2803 /* R12 will hold the new SP. */ 2804 i = cfun->machine->framesize_regs; 2805 emit_move_insn (r12, stack_pointer_rtx); 2806 emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX)); 2807 emit_insn (addPmode (r12, r12, GEN_INT (i))); 2808 emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12); 2809 } 2810 2811 for (i = 4; i <= 15; i++) 2812 if (cfun->machine->need_to_save [i]) 2813 { 2814 int seq, count; 2815 2816 for (seq = i + 1; seq <= 15 && cfun->machine->need_to_save[seq]; seq ++) 2817 ; 2818 count = seq - i; 2819 2820 if (msp430x) 2821 { 2822 /* Note: With TARGET_LARGE we still use 2823 POPM as POPX.A is two bytes bigger. */ 2824 emit_insn (gen_popm (stack_pointer_rtx, GEN_INT (seq - 1), 2825 GEN_INT (count))); 2826 i += count - 1; 2827 } 2828 else if (i == 11 - helper_n 2829 && ! msp430_is_interrupt_func () 2830 && ! is_reentrant_func () 2831 && ! is_critical_func () 2832 && crtl->args.pretend_args_size == 0 2833 /* Calling the helper takes as many bytes as the POP;RET sequence. */ 2834 && helper_n > 1 2835 && !is_eh) 2836 { 2837 emit_insn (gen_epilogue_helper (GEN_INT (helper_n))); 2838 return; 2839 } 2840 else 2841 emit_insn (gen_pop (gen_rtx_REG (Pmode, i))); 2842 } 2843 2844 if (is_eh) 2845 { 2846 /* Also pop SP, which puts us into the EH return frame. Except 2847 that you can't "pop" sp, you have to just load it off the 2848 stack. */ 2849 emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx)); 2850 } 2851 2852 if (crtl->args.pretend_args_size) 2853 emit_insn (gen_swap_and_shrink ()); 2854 2855 if (is_critical_func ()) 2856 emit_insn (gen_pop_intr_state ()); 2857 else if (is_reentrant_func ()) 2858 emit_insn (gen_enable_interrupts ()); 2859 2860 emit_jump_insn (gen_msp_return ()); 2861 } 2862 2863 /* Implements EH_RETURN_STACKADJ_RTX. Saved and used later in 2864 m32c_emit_eh_epilogue. */ 2865 rtx 2866 msp430_eh_return_stackadj_rtx (void) 2867 { 2868 if (!cfun->machine->eh_stack_adjust) 2869 { 2870 rtx sa; 2871 2872 sa = gen_rtx_REG (Pmode, 15); 2873 cfun->machine->eh_stack_adjust = sa; 2874 } 2875 return cfun->machine->eh_stack_adjust; 2876 } 2877 2878 /* This function is called before reload, to "fix" the stack in 2879 preparation for an EH return. */ 2880 void 2881 msp430_expand_eh_return (rtx eh_handler) 2882 { 2883 /* These are all Pmode */ 2884 rtx ap, sa, ra, tmp; 2885 2886 ap = arg_pointer_rtx; 2887 sa = msp430_eh_return_stackadj_rtx (); 2888 ra = eh_handler; 2889 2890 tmp = ap; 2891 tmp = gen_rtx_PLUS (Pmode, ap, sa); 2892 tmp = plus_constant (Pmode, tmp, TARGET_LARGE ? -4 : -2); 2893 tmp = gen_rtx_MEM (Pmode, tmp); 2894 emit_move_insn (tmp, ra); 2895 } 2896 2897 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA 2898 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra 2899 void 2900 msp430_init_dwarf_reg_sizes_extra (tree address) 2901 { 2902 int i; 2903 rtx addr = expand_normal (address); 2904 rtx mem = gen_rtx_MEM (BLKmode, addr); 2905 2906 /* This needs to match msp430_unwind_word_mode (above). */ 2907 if (!msp430x) 2908 return; 2909 2910 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 2911 { 2912 unsigned int dnum = DWARF_FRAME_REGNUM (i); 2913 unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1); 2914 2915 if (rnum < DWARF_FRAME_REGISTERS) 2916 { 2917 HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode); 2918 2919 emit_move_insn (adjust_address (mem, QImode, offset), 2920 gen_int_mode (4, QImode)); 2921 } 2922 } 2923 } 2924 2925 /* This is a list of MD patterns that implement fixed-count shifts. */ 2926 static struct 2927 { 2928 const char *name; 2929 int count; 2930 int need_430x; 2931 rtx (*genfunc)(rtx,rtx); 2932 } 2933 const_shift_helpers[] = 2934 { 2935 #define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G } 2936 2937 CSH ("slli", 1, 1, slli_1), 2938 CSH ("slll", 1, 1, slll_1), 2939 CSH ("slll", 2, 1, slll_2), 2940 2941 CSH ("srai", 1, 0, srai_1), 2942 CSH ("sral", 1, 0, sral_1), 2943 CSH ("sral", 2, 0, sral_2), 2944 2945 CSH ("srll", 1, 0, srll_1), 2946 CSH ("srll", 2, 1, srll_2x), 2947 { 0, 0, 0, 0 } 2948 #undef CSH 2949 }; 2950 2951 /* The MSP430 ABI defines a number of helper functions that should be 2952 used for, for example, 32-bit shifts. This function is called to 2953 emit such a function, using the table above to optimize some 2954 cases. */ 2955 void 2956 msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants) 2957 { 2958 rtx c, f; 2959 char *helper_const = NULL; 2960 int arg2 = 13; 2961 int arg1sz = 1; 2962 machine_mode arg0mode = GET_MODE (operands[0]); 2963 machine_mode arg1mode = GET_MODE (operands[1]); 2964 machine_mode arg2mode = GET_MODE (operands[2]); 2965 int have_430x = msp430x ? 1 : 0; 2966 2967 if (CONST_INT_P (operands[2])) 2968 { 2969 int i; 2970 2971 for (i=0; const_shift_helpers[i].name; i++) 2972 { 2973 if (const_shift_helpers[i].need_430x <= have_430x 2974 && strcmp (helper_name, const_shift_helpers[i].name) == 0 2975 && INTVAL (operands[2]) == const_shift_helpers[i].count) 2976 { 2977 emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1])); 2978 return; 2979 } 2980 } 2981 } 2982 2983 if (arg1mode == VOIDmode) 2984 arg1mode = arg0mode; 2985 if (arg2mode == VOIDmode) 2986 arg2mode = arg0mode; 2987 2988 if (arg1mode == SImode) 2989 { 2990 arg2 = 14; 2991 arg1sz = 2; 2992 } 2993 2994 if (const_variants 2995 && CONST_INT_P (operands[2]) 2996 && INTVAL (operands[2]) >= 1 2997 && INTVAL (operands[2]) <= 15) 2998 { 2999 /* Note that the INTVAL is limited in value and length by the conditional above. */ 3000 int len = strlen (helper_name) + 4; 3001 helper_const = (char *) xmalloc (len); 3002 snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2])); 3003 } 3004 3005 emit_move_insn (gen_rtx_REG (arg1mode, 12), 3006 operands[1]); 3007 if (!helper_const) 3008 emit_move_insn (gen_rtx_REG (arg2mode, arg2), 3009 operands[2]); 3010 3011 c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12), 3012 gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name), 3013 GEN_INT (0)); 3014 c = emit_call_insn (c); 3015 RTL_CONST_CALL_P (c) = 1; 3016 3017 f = 0; 3018 use_regs (&f, 12, arg1sz); 3019 if (!helper_const) 3020 use_regs (&f, arg2, 1); 3021 add_function_usage_to (c, f); 3022 3023 emit_move_insn (operands[0], 3024 gen_rtx_REG (arg0mode, 12)); 3025 } 3026 3027 /* Called by cbranch<mode>4 to coerce operands into usable forms. */ 3028 void 3029 msp430_fixup_compare_operands (machine_mode my_mode, rtx * operands) 3030 { 3031 /* constants we're looking for, not constants which are allowed. */ 3032 int const_op_idx = 1; 3033 3034 if (msp430_reversible_cmp_operator (operands[0], VOIDmode)) 3035 const_op_idx = 2; 3036 3037 if (GET_CODE (operands[const_op_idx]) != REG 3038 && GET_CODE (operands[const_op_idx]) != MEM) 3039 operands[const_op_idx] = copy_to_mode_reg (my_mode, operands[const_op_idx]); 3040 } 3041 3042 /* Simplify_gen_subreg() doesn't handle memory references the way we 3043 need it to below, so we use this function for when we must get a 3044 valid subreg in a "natural" state. */ 3045 rtx 3046 msp430_subreg (machine_mode mode, rtx r, machine_mode omode, int byte) 3047 { 3048 rtx rv; 3049 3050 if (GET_CODE (r) == SUBREG 3051 && SUBREG_BYTE (r) == 0) 3052 { 3053 rtx ireg = SUBREG_REG (r); 3054 machine_mode imode = GET_MODE (ireg); 3055 3056 /* special case for (HI (SI (PSI ...), 0)) */ 3057 if (imode == PSImode 3058 && mode == HImode 3059 && byte == 0) 3060 rv = gen_rtx_SUBREG (mode, ireg, byte); 3061 else 3062 rv = simplify_gen_subreg (mode, ireg, imode, byte); 3063 } 3064 else if (GET_CODE (r) == MEM) 3065 rv = adjust_address (r, mode, byte); 3066 else if (GET_CODE (r) == SYMBOL_REF 3067 && (byte == 0 || byte == 2) 3068 && mode == HImode) 3069 { 3070 rv = gen_rtx_ZERO_EXTRACT (HImode, r, GEN_INT (16), GEN_INT (8*byte)); 3071 rv = gen_rtx_CONST (HImode, r); 3072 } 3073 else 3074 rv = simplify_gen_subreg (mode, r, omode, byte); 3075 3076 if (!rv) 3077 gcc_unreachable (); 3078 3079 return rv; 3080 } 3081 3082 /* Called by movsi_x to generate the HImode operands. */ 3083 void 3084 msp430_split_movsi (rtx *operands) 3085 { 3086 rtx op00, op02, op10, op12; 3087 3088 op00 = msp430_subreg (HImode, operands[0], SImode, 0); 3089 op02 = msp430_subreg (HImode, operands[0], SImode, 2); 3090 3091 if (GET_CODE (operands[1]) == CONST 3092 || GET_CODE (operands[1]) == SYMBOL_REF) 3093 { 3094 op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0)); 3095 op10 = gen_rtx_CONST (HImode, op10); 3096 op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16)); 3097 op12 = gen_rtx_CONST (HImode, op12); 3098 } 3099 else 3100 { 3101 op10 = msp430_subreg (HImode, operands[1], SImode, 0); 3102 op12 = msp430_subreg (HImode, operands[1], SImode, 2); 3103 } 3104 3105 if (rtx_equal_p (operands[0], operands[1])) 3106 { 3107 operands[2] = op02; 3108 operands[4] = op12; 3109 operands[3] = op00; 3110 operands[5] = op10; 3111 } 3112 else if (rtx_equal_p (op00, op12) 3113 /* Catch the case where we are loading (rN, rN+1) from mem (rN). */ 3114 || (REG_P (op00) && reg_mentioned_p (op00, op10)) 3115 /* Or storing (rN) into mem (rN). */ 3116 || (REG_P (op10) && reg_mentioned_p (op10, op00)) 3117 ) 3118 { 3119 operands[2] = op02; 3120 operands[4] = op12; 3121 operands[3] = op00; 3122 operands[5] = op10; 3123 } 3124 else 3125 { 3126 operands[2] = op00; 3127 operands[4] = op10; 3128 operands[3] = op02; 3129 operands[5] = op12; 3130 } 3131 } 3132 3133 3134 /* The MSPABI specifies the names of various helper functions, many of 3135 which are compatible with GCC's helpers. This table maps the GCC 3136 name to the MSPABI name. */ 3137 static const struct 3138 { 3139 char const * const gcc_name; 3140 char const * const ti_name; 3141 } 3142 helper_function_name_mappings [] = 3143 { 3144 /* Floating point to/from integer conversions. */ 3145 { "__truncdfsf2", "__mspabi_cvtdf" }, 3146 { "__extendsfdf2", "__mspabi_cvtfd" }, 3147 { "__fixdfhi", "__mspabi_fixdi" }, 3148 { "__fixdfsi", "__mspabi_fixdli" }, 3149 { "__fixdfdi", "__mspabi_fixdlli" }, 3150 { "__fixunsdfhi", "__mspabi_fixdu" }, 3151 { "__fixunsdfsi", "__mspabi_fixdul" }, 3152 { "__fixunsdfdi", "__mspabi_fixdull" }, 3153 { "__fixsfhi", "__mspabi_fixfi" }, 3154 { "__fixsfsi", "__mspabi_fixfli" }, 3155 { "__fixsfdi", "__mspabi_fixflli" }, 3156 { "__fixunsfhi", "__mspabi_fixfu" }, 3157 { "__fixunsfsi", "__mspabi_fixful" }, 3158 { "__fixunsfdi", "__mspabi_fixfull" }, 3159 { "__floathisf", "__mspabi_fltif" }, 3160 { "__floatsisf", "__mspabi_fltlif" }, 3161 { "__floatdisf", "__mspabi_fltllif" }, 3162 { "__floathidf", "__mspabi_fltid" }, 3163 { "__floatsidf", "__mspabi_fltlid" }, 3164 { "__floatdidf", "__mspabi_fltllid" }, 3165 { "__floatunhisf", "__mspabi_fltuf" }, 3166 { "__floatunsisf", "__mspabi_fltulf" }, 3167 { "__floatundisf", "__mspabi_fltullf" }, 3168 { "__floatunhidf", "__mspabi_fltud" }, 3169 { "__floatunsidf", "__mspabi_fltuld" }, 3170 { "__floatundidf", "__mspabi_fltulld" }, 3171 3172 /* Floating point comparisons. */ 3173 /* GCC uses individual functions for each comparison, TI uses one 3174 compare <=> function. */ 3175 3176 /* Floating point arithmatic */ 3177 { "__adddf3", "__mspabi_addd" }, 3178 { "__addsf3", "__mspabi_addf" }, 3179 { "__divdf3", "__mspabi_divd" }, 3180 { "__divsf3", "__mspabi_divf" }, 3181 { "__muldf3", "__mspabi_mpyd" }, 3182 { "__mulsf3", "__mspabi_mpyf" }, 3183 { "__subdf3", "__mspabi_subd" }, 3184 { "__subsf3", "__mspabi_subf" }, 3185 /* GCC does not use helper functions for negation */ 3186 3187 /* Integer multiply, divide, remainder. */ 3188 { "__mulhi3", "__mspabi_mpyi" }, 3189 { "__mulsi3", "__mspabi_mpyl" }, 3190 { "__muldi3", "__mspabi_mpyll" }, 3191 #if 0 3192 /* Clarify signed vs unsigned first. */ 3193 { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */ 3194 { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */ 3195 #endif 3196 3197 { "__divhi3", "__mspabi_divi" }, 3198 { "__divsi3", "__mspabi_divli" }, 3199 { "__divdi3", "__mspabi_divlli" }, 3200 { "__udivhi3", "__mspabi_divu" }, 3201 { "__udivsi3", "__mspabi_divul" }, 3202 { "__udivdi3", "__mspabi_divull" }, 3203 { "__modhi3", "__mspabi_remi" }, 3204 { "__modsi3", "__mspabi_remli" }, 3205 { "__moddi3", "__mspabi_remlli" }, 3206 { "__umodhi3", "__mspabi_remu" }, 3207 { "__umodsi3", "__mspabi_remul" }, 3208 { "__umoddi3", "__mspabi_remull" }, 3209 3210 /* Bitwise operations. */ 3211 /* Rotation - no rotation support yet. */ 3212 /* Logical left shift - gcc already does these itself. */ 3213 /* Arithmetic left shift - gcc already does these itself. */ 3214 /* Arithmetic right shift - gcc already does these itself. */ 3215 3216 { NULL, NULL } 3217 }; 3218 3219 /* Returns true if the current MCU supports an F5xxx series 3220 hardware multiper. */ 3221 3222 bool 3223 msp430_use_f5_series_hwmult (void) 3224 { 3225 static const char * cached_match = NULL; 3226 static bool cached_result; 3227 3228 if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES) 3229 return true; 3230 3231 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO) 3232 return false; 3233 3234 if (target_mcu == cached_match) 3235 return cached_result; 3236 3237 cached_match = target_mcu; 3238 3239 if (strncasecmp (target_mcu, "msp430f5", 8) == 0) 3240 return cached_result = true; 3241 if (strncasecmp (target_mcu, "msp430fr5", 9) == 0) 3242 return cached_result = true; 3243 if (strncasecmp (target_mcu, "msp430f6", 8) == 0) 3244 return cached_result = true; 3245 3246 int i; 3247 3248 /* FIXME: This array is alpha sorted - we could use a binary search. */ 3249 for (i = ARRAY_SIZE (msp430_mcu_data); i--;) 3250 if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0) 3251 return cached_result = msp430_mcu_data[i].hwmpy == 8; 3252 3253 return cached_result = false; 3254 } 3255 3256 /* Returns true if the current MCU has a second generation 3257 32-bit hardware multiplier. */ 3258 3259 static bool 3260 use_32bit_hwmult (void) 3261 { 3262 static const char * cached_match = NULL; 3263 static bool cached_result; 3264 int i; 3265 3266 if (msp430_hwmult_type == MSP430_HWMULT_LARGE) 3267 return true; 3268 3269 if (target_mcu == NULL || msp430_hwmult_type != MSP430_HWMULT_AUTO) 3270 return false; 3271 3272 if (target_mcu == cached_match) 3273 return cached_result; 3274 3275 cached_match = target_mcu; 3276 3277 /* FIXME: This array is alpha sorted - we could use a binary search. */ 3278 for (i = ARRAY_SIZE (msp430_mcu_data); i--;) 3279 if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0) 3280 return cached_result = msp430_mcu_data[i].hwmpy == 4; 3281 3282 return cached_result = false; 3283 } 3284 3285 /* Returns true if the current MCU does not have a 3286 hardware multiplier of any kind. */ 3287 3288 static bool 3289 msp430_no_hwmult (void) 3290 { 3291 static const char * cached_match = NULL; 3292 static bool cached_result; 3293 int i; 3294 3295 if (msp430_hwmult_type == MSP430_HWMULT_NONE) 3296 return true; 3297 3298 if (msp430_hwmult_type != MSP430_HWMULT_AUTO) 3299 return false; 3300 3301 if (target_mcu == NULL) 3302 return true; 3303 3304 if (target_mcu == cached_match) 3305 return cached_result; 3306 3307 cached_match = target_mcu; 3308 3309 /* FIXME: This array is alpha sorted - we could use a binary search. */ 3310 for (i = ARRAY_SIZE (msp430_mcu_data); i--;) 3311 if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0) 3312 return cached_result = msp430_mcu_data[i].hwmpy == 0; 3313 3314 /* If we do not recognise the MCU name, we assume that it does not support 3315 any kind of hardware multiply - this is the safest assumption to make. */ 3316 return cached_result = true; 3317 } 3318 3319 /* This function does the same as the default, but it will replace GCC 3320 function names with the MSPABI-specified ones. */ 3321 3322 void 3323 msp430_output_labelref (FILE *file, const char *name) 3324 { 3325 int i; 3326 3327 for (i = 0; helper_function_name_mappings [i].gcc_name; i++) 3328 if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0) 3329 { 3330 name = helper_function_name_mappings [i].ti_name; 3331 break; 3332 } 3333 3334 /* If we have been given a specific MCU name then we may be 3335 able to make use of its hardware multiply capabilities. */ 3336 if (msp430_hwmult_type != MSP430_HWMULT_NONE) 3337 { 3338 if (strcmp ("__mspabi_mpyi", name) == 0) 3339 { 3340 if (msp430_use_f5_series_hwmult ()) 3341 name = "__mulhi2_f5"; 3342 else if (! msp430_no_hwmult ()) 3343 name = "__mulhi2"; 3344 } 3345 else if (strcmp ("__mspabi_mpyl", name) == 0) 3346 { 3347 if (msp430_use_f5_series_hwmult ()) 3348 name = "__mulsi2_f5"; 3349 else if (use_32bit_hwmult ()) 3350 name = "__mulsi2_hw32"; 3351 else if (! msp430_no_hwmult ()) 3352 name = "__mulsi2"; 3353 } 3354 } 3355 3356 fputs (name, file); 3357 } 3358 3359 /* Common code for msp430_print_operand... */ 3360 3361 static void 3362 msp430_print_operand_raw (FILE * file, rtx op) 3363 { 3364 HOST_WIDE_INT i; 3365 3366 switch (GET_CODE (op)) 3367 { 3368 case REG: 3369 fprintf (file, "%s", reg_names [REGNO (op)]); 3370 break; 3371 3372 case CONST_INT: 3373 i = INTVAL (op); 3374 if (TARGET_ASM_HEX) 3375 fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i); 3376 else 3377 fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i); 3378 break; 3379 3380 case CONST: 3381 case PLUS: 3382 case MINUS: 3383 case SYMBOL_REF: 3384 case LABEL_REF: 3385 output_addr_const (file, op); 3386 break; 3387 3388 default: 3389 print_rtl (file, op); 3390 break; 3391 } 3392 } 3393 3394 #undef TARGET_PRINT_OPERAND_ADDRESS 3395 #define TARGET_PRINT_OPERAND_ADDRESS msp430_print_operand_addr 3396 3397 /* Output to stdio stream FILE the assembler syntax for an 3398 instruction operand that is a memory reference whose address 3399 is ADDR. */ 3400 3401 static void 3402 msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr) 3403 { 3404 switch (GET_CODE (addr)) 3405 { 3406 case PLUS: 3407 msp430_print_operand_raw (file, XEXP (addr, 1)); 3408 gcc_assert (REG_P (XEXP (addr, 0))); 3409 fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]); 3410 return; 3411 3412 case REG: 3413 fprintf (file, "@"); 3414 break; 3415 3416 case CONST: 3417 case CONST_INT: 3418 case SYMBOL_REF: 3419 case LABEL_REF: 3420 fprintf (file, "&"); 3421 break; 3422 3423 default: 3424 break; 3425 } 3426 3427 msp430_print_operand_raw (file, addr); 3428 } 3429 3430 #undef TARGET_PRINT_OPERAND 3431 #define TARGET_PRINT_OPERAND msp430_print_operand 3432 3433 /* A low 16-bits of int/lower of register pair 3434 B high 16-bits of int/higher of register pair 3435 C bits 32-47 of a 64-bit value/reg 3 of a DImode value 3436 D bits 48-63 of a 64-bit value/reg 4 of a DImode value 3437 H like %B (for backwards compatibility) 3438 I inverse of value 3439 J an integer without a # prefix 3440 L like %A (for backwards compatibility) 3441 O offset of the top of the stack 3442 Q like X but generates an A postfix 3443 R inverse of condition code, unsigned. 3444 X X instruction postfix in large mode 3445 Y value - 4 3446 Z value - 1 3447 b .B or .W or .A, depending upon the mode 3448 p bit position 3449 r inverse of condition code 3450 x like X but only for pointers. */ 3451 3452 static void 3453 msp430_print_operand (FILE * file, rtx op, int letter) 3454 { 3455 rtx addr; 3456 3457 /* We can't use c, n, a, or l. */ 3458 switch (letter) 3459 { 3460 case 'Z': 3461 gcc_assert (CONST_INT_P (op)); 3462 /* Print the constant value, less one. */ 3463 fprintf (file, "#%ld", INTVAL (op) - 1); 3464 return; 3465 case 'Y': 3466 gcc_assert (CONST_INT_P (op)); 3467 /* Print the constant value, less four. */ 3468 fprintf (file, "#%ld", INTVAL (op) - 4); 3469 return; 3470 case 'I': 3471 if (GET_CODE (op) == CONST_INT) 3472 { 3473 /* Inverse of constants */ 3474 int i = INTVAL (op); 3475 fprintf (file, "%d", ~i); 3476 return; 3477 } 3478 op = XEXP (op, 0); 3479 break; 3480 case 'r': /* Conditional jump where the condition is reversed. */ 3481 switch (GET_CODE (op)) 3482 { 3483 case EQ: fprintf (file, "NE"); break; 3484 case NE: fprintf (file, "EQ"); break; 3485 case GEU: fprintf (file, "LO"); break; 3486 case LTU: fprintf (file, "HS"); break; 3487 case GE: fprintf (file, "L"); break; 3488 case LT: fprintf (file, "GE"); break; 3489 /* Assume these have reversed operands. */ 3490 case GTU: fprintf (file, "HS"); break; 3491 case LEU: fprintf (file, "LO"); break; 3492 case GT: fprintf (file, "GE"); break; 3493 case LE: fprintf (file, "L"); break; 3494 default: 3495 msp430_print_operand_raw (file, op); 3496 break; 3497 } 3498 return; 3499 case 'R': /* Conditional jump where the operands are reversed. */ 3500 switch (GET_CODE (op)) 3501 { 3502 case GTU: fprintf (file, "LO"); break; 3503 case LEU: fprintf (file, "HS"); break; 3504 case GT: fprintf (file, "L"); break; 3505 case LE: fprintf (file, "GE"); break; 3506 default: 3507 msp430_print_operand_raw (file, op); 3508 break; 3509 } 3510 return; 3511 case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */ 3512 gcc_assert (CONST_INT_P (op)); 3513 fprintf (file, "#%d", 1 << INTVAL (op)); 3514 return; 3515 case 'b': 3516 switch (GET_MODE (op)) 3517 { 3518 case QImode: fprintf (file, ".B"); return; 3519 case HImode: fprintf (file, ".W"); return; 3520 case PSImode: fprintf (file, ".A"); return; 3521 case SImode: fprintf (file, ".A"); return; 3522 default: 3523 return; 3524 } 3525 case 'A': 3526 case 'L': /* Low half. */ 3527 switch (GET_CODE (op)) 3528 { 3529 case MEM: 3530 op = adjust_address (op, Pmode, 0); 3531 break; 3532 case REG: 3533 break; 3534 case CONST_INT: 3535 op = GEN_INT (INTVAL (op) & 0xffff); 3536 letter = 0; 3537 break; 3538 default: 3539 /* If you get here, figure out a test case :-) */ 3540 gcc_unreachable (); 3541 } 3542 break; 3543 case 'B': 3544 case 'H': /* high half */ 3545 switch (GET_CODE (op)) 3546 { 3547 case MEM: 3548 op = adjust_address (op, Pmode, 2); 3549 break; 3550 case REG: 3551 op = gen_rtx_REG (Pmode, REGNO (op) + 1); 3552 break; 3553 case CONST_INT: 3554 op = GEN_INT (INTVAL (op) >> 16); 3555 letter = 0; 3556 break; 3557 default: 3558 /* If you get here, figure out a test case :-) */ 3559 gcc_unreachable (); 3560 } 3561 break; 3562 case 'C': 3563 switch (GET_CODE (op)) 3564 { 3565 case MEM: 3566 op = adjust_address (op, Pmode, 3); 3567 break; 3568 case REG: 3569 op = gen_rtx_REG (Pmode, REGNO (op) + 2); 3570 break; 3571 case CONST_INT: 3572 op = GEN_INT ((long long) INTVAL (op) >> 32); 3573 letter = 0; 3574 break; 3575 default: 3576 /* If you get here, figure out a test case :-) */ 3577 gcc_unreachable (); 3578 } 3579 break; 3580 case 'D': 3581 switch (GET_CODE (op)) 3582 { 3583 case MEM: 3584 op = adjust_address (op, Pmode, 4); 3585 break; 3586 case REG: 3587 op = gen_rtx_REG (Pmode, REGNO (op) + 3); 3588 break; 3589 case CONST_INT: 3590 op = GEN_INT ((long long) INTVAL (op) >> 48); 3591 letter = 0; 3592 break; 3593 default: 3594 /* If you get here, figure out a test case :-) */ 3595 gcc_unreachable (); 3596 } 3597 break; 3598 3599 case 'X': 3600 /* This is used to turn, for example, an ADD opcode into an ADDX 3601 opcode when we're using 20-bit addresses. */ 3602 if (TARGET_LARGE || GET_MODE (op) == PSImode) 3603 fprintf (file, "X"); 3604 /* We don't care which operand we use, but we want 'X' in the MD 3605 file, so we do it this way. */ 3606 return; 3607 3608 case 'x': 3609 /* Similarly, but only for PSImodes. BIC, for example, needs this. */ 3610 if (GET_MODE (op) == PSImode) 3611 fprintf (file, "X"); 3612 return; 3613 3614 case 'Q': 3615 /* Likewise, for BR -> BRA. */ 3616 if (TARGET_LARGE) 3617 fprintf (file, "A"); 3618 return; 3619 3620 case 'O': 3621 /* Computes the offset to the top of the stack for the current frame. 3622 This has to be done here rather than in, say, msp430_expand_builtin() 3623 because builtins are expanded before the frame layout is determined. */ 3624 fprintf (file, "%d", 3625 msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM) 3626 - (TARGET_LARGE ? 4 : 2)); 3627 return; 3628 3629 case 'J': 3630 gcc_assert (GET_CODE (op) == CONST_INT); 3631 case 0: 3632 break; 3633 default: 3634 output_operand_lossage ("invalid operand prefix"); 3635 return; 3636 } 3637 3638 switch (GET_CODE (op)) 3639 { 3640 case REG: 3641 msp430_print_operand_raw (file, op); 3642 break; 3643 3644 case MEM: 3645 addr = XEXP (op, 0); 3646 msp430_print_operand_addr (file, GET_MODE (op), addr); 3647 break; 3648 3649 case CONST: 3650 if (GET_CODE (XEXP (op, 0)) == ZERO_EXTRACT) 3651 { 3652 op = XEXP (op, 0); 3653 switch (INTVAL (XEXP (op, 2))) 3654 { 3655 case 0: 3656 fprintf (file, "#lo ("); 3657 msp430_print_operand_raw (file, XEXP (op, 0)); 3658 fprintf (file, ")"); 3659 break; 3660 3661 case 16: 3662 fprintf (file, "#hi ("); 3663 msp430_print_operand_raw (file, XEXP (op, 0)); 3664 fprintf (file, ")"); 3665 break; 3666 3667 default: 3668 output_operand_lossage ("invalid zero extract"); 3669 break; 3670 } 3671 break; 3672 } 3673 /* Fall through. */ 3674 case CONST_INT: 3675 case SYMBOL_REF: 3676 case LABEL_REF: 3677 if (letter == 0) 3678 fprintf (file, "#"); 3679 msp430_print_operand_raw (file, op); 3680 break; 3681 3682 case EQ: fprintf (file, "EQ"); break; 3683 case NE: fprintf (file, "NE"); break; 3684 case GEU: fprintf (file, "HS"); break; 3685 case LTU: fprintf (file, "LO"); break; 3686 case GE: fprintf (file, "GE"); break; 3687 case LT: fprintf (file, "L"); break; 3688 3689 default: 3690 print_rtl (file, op); 3691 break; 3692 } 3693 } 3694 3695 3696 /* Frame stuff. */ 3697 3698 rtx 3699 msp430_return_addr_rtx (int count) 3700 { 3701 int ra_size; 3702 if (count) 3703 return NULL_RTX; 3704 3705 ra_size = TARGET_LARGE ? 4 : 2; 3706 if (crtl->args.pretend_args_size) 3707 ra_size += 2; 3708 3709 return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size))); 3710 } 3711 3712 rtx 3713 msp430_incoming_return_addr_rtx (void) 3714 { 3715 return gen_rtx_MEM (Pmode, stack_pointer_rtx); 3716 } 3717 3718 /* Instruction generation stuff. */ 3719 3720 /* Generate a sequence of instructions to sign-extend an HI 3721 value into an SI value. Handles the tricky case where 3722 we are overwriting the destination. */ 3723 3724 const char * 3725 msp430x_extendhisi (rtx * operands) 3726 { 3727 if (REGNO (operands[0]) == REGNO (operands[1])) 3728 /* Low word of dest == source word. */ 3729 return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */ 3730 3731 if (! msp430x) 3732 /* Note: This sequence is approximately the same length as invoking a helper 3733 function to perform the sign-extension, as in: 3734 3735 MOV.W %1, %L0 3736 MOV.W %1, r12 3737 CALL __mspabi_srai_15 3738 MOV.W r12, %H0 3739 3740 but this version does not involve any function calls or using argument 3741 registers, so it reduces register pressure. */ 3742 return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */ 3743 3744 if (REGNO (operands[0]) + 1 == REGNO (operands[1])) 3745 /* High word of dest == source word. */ 3746 return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */ 3747 3748 /* No overlap between dest and source. */ 3749 return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */ 3750 } 3751 3752 /* Likewise for logical right shifts. */ 3753 const char * 3754 msp430x_logical_shift_right (rtx amount) 3755 { 3756 /* The MSP430X's logical right shift instruction - RRUM - does 3757 not use an extension word, so we cannot encode a repeat count. 3758 Try various alternatives to work around this. If the count 3759 is in a register we are stuck, hence the assert. */ 3760 gcc_assert (CONST_INT_P (amount)); 3761 3762 if (INTVAL (amount) <= 0 3763 || INTVAL (amount) >= 16) 3764 return "# nop logical shift."; 3765 3766 if (INTVAL (amount) > 0 3767 && INTVAL (amount) < 5) 3768 return "rrum.w\t%2, %0"; /* Two bytes. */ 3769 3770 if (INTVAL (amount) > 4 3771 && INTVAL (amount) < 9) 3772 return "rrum.w\t#4, %0 { rrum.w\t%Y2, %0 "; /* Four bytes. */ 3773 3774 /* First we logically shift right by one. Now we know 3775 that the top bit is zero and we can use the arithmetic 3776 right shift instruction to perform the rest of the shift. */ 3777 return "rrum.w\t#1, %0 { rpt\t%Z2 { rrax.w\t%0"; /* Six bytes. */ 3778 } 3779 3780 struct gcc_target targetm = TARGET_INITIALIZER; 3781 3782 #include "gt-msp430.h" 3783