1 /* rl78-parse.y Renesas RL78 parser 2 Copyright (C) 2011-2014 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to the Free 18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 %{ 21 22 #include "as.h" 23 #include "safe-ctype.h" 24 #include "rl78-defs.h" 25 26 static int rl78_lex (void); 27 28 /* Ok, here are the rules for using these macros... 29 30 B*() is used to specify the base opcode bytes. Fields to be filled 31 in later, leave zero. Call this first. 32 33 F() and FE() are used to fill in fields within the base opcode bytes. You MUST 34 call B*() before any F() or FE(). 35 36 [UN]*O*(), PC*() appends operands to the end of the opcode. You 37 must call P() and B*() before any of these, so that the fixups 38 have the right byte location. 39 O = signed, UO = unsigned, NO = negated, PC = pcrel 40 41 IMM() adds an immediate and fills in the field for it. 42 NIMM() same, but negates the immediate. 43 NBIMM() same, but negates the immediate, for sbb. 44 DSP() adds a displacement, and fills in the field for it. 45 46 Note that order is significant for the O, IMM, and DSP macros, as 47 they append their data to the operand buffer in the order that you 48 call them. 49 50 Use "disp" for displacements whenever possible; this handles the 51 "0" case properly. */ 52 53 #define B1(b1) rl78_base1 (b1) 54 #define B2(b1, b2) rl78_base2 (b1, b2) 55 #define B3(b1, b2, b3) rl78_base3 (b1, b2, b3) 56 #define B4(b1, b2, b3, b4) rl78_base4 (b1, b2, b3, b4) 57 58 /* POS is bits from the MSB of the first byte to the LSB of the last byte. */ 59 #define F(val,pos,sz) rl78_field (val, pos, sz) 60 #define FE(exp,pos,sz) rl78_field (exp_val (exp), pos, sz); 61 62 #define O1(v) rl78_op (v, 1, RL78REL_DATA) 63 #define O2(v) rl78_op (v, 2, RL78REL_DATA) 64 #define O3(v) rl78_op (v, 3, RL78REL_DATA) 65 #define O4(v) rl78_op (v, 4, RL78REL_DATA) 66 67 #define PC1(v) rl78_op (v, 1, RL78REL_PCREL) 68 #define PC2(v) rl78_op (v, 2, RL78REL_PCREL) 69 #define PC3(v) rl78_op (v, 3, RL78REL_PCREL) 70 71 #define IMM(v,pos) F (immediate (v, RL78REL_SIGNED, pos), pos, 2); \ 72 if (v.X_op != O_constant && v.X_op != O_big) rl78_linkrelax_imm (pos) 73 #define NIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE, pos), pos, 2) 74 #define NBIMM(v,pos) F (immediate (v, RL78REL_NEGATIVE_BORROW, pos), pos, 2) 75 #define DSP(v,pos,msz) if (!v.X_md) rl78_relax (RL78_RELAX_DISP, pos); \ 76 else rl78_linkrelax_dsp (pos); \ 77 F (displacement (v, msz), pos, 2) 78 79 #define id24(a,b2,b3) B3 (0xfb+a, b2, b3) 80 81 static int expr_is_sfr (expressionS); 82 static int expr_is_saddr (expressionS); 83 static int expr_is_word_aligned (expressionS); 84 static int exp_val (expressionS exp); 85 86 static int need_flag = 0; 87 static int rl78_in_brackets = 0; 88 static int rl78_last_token = 0; 89 static char * rl78_init_start; 90 static char * rl78_last_exp_start = 0; 91 static int rl78_bit_insn = 0; 92 93 #define YYDEBUG 1 94 #define YYERROR_VERBOSE 1 95 96 #define NOT_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFF1F") 97 #define SA(e) if (!expr_is_saddr (e)) NOT_SADDR; 98 99 #define NOT_SFR rl78_error ("Expression not 0xFFF00 to 0xFFFFF") 100 #define SFR(e) if (!expr_is_sfr (e)) NOT_SFR; 101 102 #define NOT_SFR_OR_SADDR rl78_error ("Expression not 0xFFE20 to 0xFFFFF") 103 104 #define NOT_ES if (rl78_has_prefix()) rl78_error ("ES: prefix not allowed here"); 105 106 #define WA(x) if (!expr_is_word_aligned (x)) rl78_error ("Expression not word-aligned"); 107 108 static void check_expr_is_bit_index (expressionS); 109 #define Bit(e) check_expr_is_bit_index (e); 110 111 /* Returns TRUE (non-zero) if the expression is a constant in the 112 given range. */ 113 static int check_expr_is_const (expressionS, int vmin, int vmax); 114 115 /* Convert a "regb" value to a "reg_xbc" value. Error if other 116 registers are passed. Needed to avoid reduce-reduce conflicts. */ 117 static int 118 reg_xbc (int reg) 119 { 120 switch (reg) 121 { 122 case 0: /* X */ 123 return 0x10; 124 case 3: /* B */ 125 return 0x20; 126 case 2: /* C */ 127 return 0x30; 128 default: 129 rl78_error ("Only X, B, or C allowed here"); 130 return 0; 131 } 132 } 133 134 %} 135 136 %name-prefix="rl78_" 137 138 %union { 139 int regno; 140 expressionS exp; 141 } 142 143 %type <regno> regb regb_na regw regw_na FLAG sfr 144 %type <regno> A X B C D E H L AX BC DE HL 145 %type <exp> EXPR 146 147 %type <regno> addsub addsubw andor1 bt_bf setclr1 oneclrb oneclrw 148 %type <regno> incdec incdecw 149 150 %token A X B C D E H L AX BC DE HL 151 %token SPL SPH PSW CS ES PMC MEM 152 %token FLAG SP CY 153 %token RB0 RB1 RB2 RB3 154 155 %token EXPR UNKNOWN_OPCODE IS_OPCODE 156 157 %token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW 158 159 %token ADD ADDC ADDW AND_ AND1 160 /* BC is also a register pair */ 161 %token BF BH BNC BNH BNZ BR BRK BRK1 BT BTCLR BZ 162 %token CALL CALLT CLR1 CLRB CLRW CMP CMP0 CMPS CMPW 163 %token DEC DECW DI DIVHU DIVWU 164 %token EI 165 %token HALT 166 %token INC INCW 167 %token MACH MACHU MOV MOV1 MOVS MOVW MULH MULHU MULU 168 %token NOP NOT1 169 %token ONEB ONEW OR OR1 170 %token POP PUSH 171 %token RET RETI RETB ROL ROLC ROLWC ROR RORC 172 %token SAR SARW SEL SET1 SHL SHLW SHR SHRW 173 %token SKC SKH SKNC SKNH SKNZ SKZ STOP SUB SUBC SUBW 174 %token XCH XCHW XOR XOR1 175 176 %% 177 /* ====================================================================== */ 178 179 statement : 180 181 UNKNOWN_OPCODE 182 { as_bad (_("Unknown opcode: %s"), rl78_init_start); } 183 184 /* The opcodes are listed in approximately alphabetical order. */ 185 186 /* For reference: 187 188 sfr = special function register - symbol, 0xFFF00 to 0xFFFFF 189 sfrp = special function register - symbol, 0xFFF00 to 0xFFFFE, even only 190 saddr = 0xFFE20 to 0xFFF1F 191 saddrp = 0xFFE20 to 0xFFF1E, even only 192 193 addr20 = 0x00000 to 0xFFFFF 194 addr16 = 0x00000 to 0x0FFFF, even only for 16-bit ops 195 addr5 = 0x00000 to 0x000BE, even only 196 */ 197 198 /* ---------------------------------------------------------------------- */ 199 200 /* addsub is ADD, ADDC, SUB, SUBC, AND, OR, XOR, and parts of CMP. */ 201 202 | addsub A ',' '#' EXPR 203 { B1 (0x0c|$1); O1 ($5); } 204 205 | addsub EXPR {SA($2)} ',' '#' EXPR 206 { B1 (0x0a|$1); O1 ($2); O1 ($6); } 207 208 | addsub A ',' A 209 { B2 (0x61, 0x01|$1); } 210 211 | addsub A ',' regb_na 212 { B2 (0x61, 0x08|$1); F ($4, 13, 3); } 213 214 | addsub regb_na ',' A 215 { B2 (0x61, 0x00|$1); F ($2, 13, 3); } 216 217 | addsub A ',' EXPR {SA($4)} 218 { B1 (0x0b|$1); O1 ($4); } 219 220 | addsub A ',' opt_es '!' EXPR 221 { B1 (0x0f|$1); O2 ($6); rl78_linkrelax_addr16 (); } 222 223 | addsub A ',' opt_es '[' HL ']' 224 { B1 (0x0d|$1); } 225 226 | addsub A ',' opt_es '[' HL '+' EXPR ']' 227 { B1 (0x0e|$1); O1 ($8); } 228 229 | addsub A ',' opt_es '[' HL '+' B ']' 230 { B2 (0x61, 0x80|$1); } 231 232 | addsub A ',' opt_es '[' HL '+' C ']' 233 { B2 (0x61, 0x82|$1); } 234 235 236 237 | addsub opt_es '!' EXPR ',' '#' EXPR 238 { if ($1 != 0x40) 239 { rl78_error ("Only CMP takes these operands"); } 240 else 241 { B1 (0x00|$1); O2 ($4); O1 ($7); rl78_linkrelax_addr16 (); } 242 } 243 244 /* ---------------------------------------------------------------------- */ 245 246 | addsubw AX ',' '#' EXPR 247 { B1 (0x04|$1); O2 ($5); } 248 249 | addsubw AX ',' regw 250 { B1 (0x01|$1); F ($4, 5, 2); } 251 252 | addsubw AX ',' EXPR {SA($4)} 253 { B1 (0x06|$1); O1 ($4); } 254 255 | addsubw AX ',' opt_es '!' EXPR 256 { B1 (0x02|$1); O2 ($6); rl78_linkrelax_addr16 (); } 257 258 | addsubw AX ',' opt_es '[' HL '+' EXPR ']' 259 { B2 (0x61, 0x09|$1); O1 ($8); } 260 261 | addsubw AX ',' opt_es '[' HL ']' 262 { B4 (0x61, 0x09|$1, 0, 0); } 263 264 | addsubw SP ',' '#' EXPR 265 { B1 ($1 ? 0x20 : 0x10); O1 ($5); 266 if ($1 == 0x40) 267 rl78_error ("CMPW SP,#imm not allowed"); 268 } 269 270 /* ---------------------------------------------------------------------- */ 271 272 | andor1 CY ',' sfr '.' EXPR {Bit($6)} 273 { B3 (0x71, 0x08|$1, $4); FE ($6, 9, 3); } 274 275 | andor1 CY ',' EXPR '.' EXPR {Bit($6)} 276 { if (expr_is_sfr ($4)) 277 { B2 (0x71, 0x08|$1); FE ($6, 9, 3); O1 ($4); } 278 else if (expr_is_saddr ($4)) 279 { B2 (0x71, 0x00|$1); FE ($6, 9, 3); O1 ($4); } 280 else 281 NOT_SFR_OR_SADDR; 282 } 283 284 | andor1 CY ',' A '.' EXPR {Bit($6)} 285 { B2 (0x71, 0x88|$1); FE ($6, 9, 3); } 286 287 | andor1 CY ',' opt_es '[' HL ']' '.' EXPR {Bit($9)} 288 { B2 (0x71, 0x80|$1); FE ($9, 9, 3); } 289 290 /* ---------------------------------------------------------------------- */ 291 292 | BC '$' EXPR 293 { B1 (0xdc); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 294 295 | BNC '$' EXPR 296 { B1 (0xde); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 297 298 | BZ '$' EXPR 299 { B1 (0xdd); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 300 301 | BNZ '$' EXPR 302 { B1 (0xdf); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 303 304 | BH '$' EXPR 305 { B2 (0x61, 0xc3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 306 307 | BNH '$' EXPR 308 { B2 (0x61, 0xd3); PC1 ($3); rl78_relax (RL78_RELAX_BRANCH, 0); } 309 310 /* ---------------------------------------------------------------------- */ 311 312 | bt_bf sfr '.' EXPR ',' '$' EXPR 313 { B3 (0x31, 0x80|$1, $2); FE ($4, 9, 3); PC1 ($7); } 314 315 | bt_bf EXPR '.' EXPR ',' '$' EXPR 316 { if (expr_is_sfr ($2)) 317 { B2 (0x31, 0x80|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); } 318 else if (expr_is_saddr ($2)) 319 { B2 (0x31, 0x00|$1); FE ($4, 9, 3); O1 ($2); PC1 ($7); } 320 else 321 NOT_SFR_OR_SADDR; 322 } 323 324 | bt_bf A '.' EXPR ',' '$' EXPR 325 { B2 (0x31, 0x01|$1); FE ($4, 9, 3); PC1 ($7); } 326 327 | bt_bf opt_es '[' HL ']' '.' EXPR ',' '$' EXPR 328 { B2 (0x31, 0x81|$1); FE ($7, 9, 3); PC1 ($10); } 329 330 /* ---------------------------------------------------------------------- */ 331 332 | BR AX 333 { B2 (0x61, 0xcb); } 334 335 | BR '$' EXPR 336 { B1 (0xef); PC1 ($3); } 337 338 | BR '$' '!' EXPR 339 { B1 (0xee); PC2 ($4); rl78_linkrelax_branch (); } 340 341 | BR '!' EXPR 342 { B1 (0xed); O2 ($3); rl78_linkrelax_branch (); } 343 344 | BR '!' '!' EXPR 345 { B1 (0xec); O3 ($4); rl78_linkrelax_branch (); } 346 347 /* ---------------------------------------------------------------------- */ 348 349 | BRK 350 { B2 (0x61, 0xcc); } 351 352 | BRK1 353 { B1 (0xff); } 354 355 /* ---------------------------------------------------------------------- */ 356 357 | CALL regw 358 { B2 (0x61, 0xca); F ($2, 10, 2); } 359 360 | CALL '$' '!' EXPR 361 { B1 (0xfe); PC2 ($4); } 362 363 | CALL '!' EXPR 364 { B1 (0xfd); O2 ($3); } 365 366 | CALL '!' '!' EXPR 367 { B1 (0xfc); O3 ($4); rl78_linkrelax_branch (); } 368 369 | CALLT '[' EXPR ']' 370 { if ($3.X_op != O_constant) 371 rl78_error ("CALLT requires a numeric address"); 372 else 373 { 374 int i = $3.X_add_number; 375 if (i < 0x80 || i > 0xbe) 376 rl78_error ("CALLT address not 0x80..0xbe"); 377 else if (i & 1) 378 rl78_error ("CALLT address not even"); 379 else 380 { 381 B2 (0x61, 0x84); 382 F ((i >> 1) & 7, 9, 3); 383 F ((i >> 4) & 7, 14, 2); 384 } 385 } 386 } 387 388 /* ---------------------------------------------------------------------- */ 389 390 | setclr1 CY 391 { B2 (0x71, $1 ? 0x88 : 0x80); } 392 393 | setclr1 sfr '.' EXPR 394 { B3 (0x71, 0x0a|$1, $2); FE ($4, 9, 3); } 395 396 | setclr1 EXPR '.' EXPR 397 { if (expr_is_sfr ($2)) 398 { B2 (0x71, 0x0a|$1); FE ($4, 9, 3); O1 ($2); } 399 else if (expr_is_saddr ($2)) 400 { B2 (0x71, 0x02|$1); FE ($4, 9, 3); O1 ($2); } 401 else 402 NOT_SFR_OR_SADDR; 403 } 404 405 | setclr1 A '.' EXPR 406 { B2 (0x71, 0x8a|$1); FE ($4, 9, 3); } 407 408 | setclr1 opt_es '!' EXPR '.' EXPR 409 { B2 (0x71, 0x00+$1*0x08); FE ($6, 9, 3); O2 ($4); rl78_linkrelax_addr16 (); } 410 411 | setclr1 opt_es '[' HL ']' '.' EXPR 412 { B2 (0x71, 0x82|$1); FE ($7, 9, 3); } 413 414 /* ---------------------------------------------------------------------- */ 415 416 | oneclrb A 417 { B1 (0xe1|$1); } 418 | oneclrb X 419 { B1 (0xe0|$1); } 420 | oneclrb B 421 { B1 (0xe3|$1); } 422 | oneclrb C 423 { B1 (0xe2|$1); } 424 425 | oneclrb EXPR {SA($2)} 426 { B1 (0xe4|$1); O1 ($2); } 427 428 | oneclrb opt_es '!' EXPR 429 { B1 (0xe5|$1); O2 ($4); rl78_linkrelax_addr16 (); } 430 431 /* ---------------------------------------------------------------------- */ 432 433 | oneclrw AX 434 { B1 (0xe6|$1); } 435 | oneclrw BC 436 { B1 (0xe7|$1); } 437 438 /* ---------------------------------------------------------------------- */ 439 440 | CMP0 A 441 { B1 (0xd1); } 442 443 | CMP0 X 444 { B1 (0xd0); } 445 446 | CMP0 B 447 { B1 (0xd3); } 448 449 | CMP0 C 450 { B1 (0xd2); } 451 452 | CMP0 EXPR {SA($2)} 453 { B1 (0xd4); O1 ($2); } 454 455 | CMP0 opt_es '!' EXPR 456 { B1 (0xd5); O2 ($4); rl78_linkrelax_addr16 (); } 457 458 /* ---------------------------------------------------------------------- */ 459 460 | CMPS X ',' opt_es '[' HL '+' EXPR ']' 461 { B2 (0x61, 0xde); O1 ($8); } 462 463 /* ---------------------------------------------------------------------- */ 464 465 | incdec regb 466 { B1 (0x80|$1); F ($2, 5, 3); } 467 468 | incdec EXPR {SA($2)} 469 { B1 (0xa4|$1); O1 ($2); } 470 | incdec '!' EXPR 471 { B1 (0xa0|$1); O2 ($3); rl78_linkrelax_addr16 (); } 472 | incdec ES ':' '!' EXPR 473 { B2 (0x11, 0xa0|$1); O2 ($5); } 474 | incdec '[' HL '+' EXPR ']' 475 { B2 (0x61, 0x59+$1); O1 ($5); } 476 | incdec ES ':' '[' HL '+' EXPR ']' 477 { B3 (0x11, 0x61, 0x59+$1); O1 ($7); } 478 479 /* ---------------------------------------------------------------------- */ 480 481 | incdecw regw 482 { B1 (0xa1|$1); F ($2, 5, 2); } 483 484 | incdecw EXPR {SA($2)} 485 { B1 (0xa6|$1); O1 ($2); } 486 487 | incdecw opt_es '!' EXPR 488 { B1 (0xa2|$1); O2 ($4); rl78_linkrelax_addr16 (); } 489 490 | incdecw opt_es '[' HL '+' EXPR ']' 491 { B2 (0x61, 0x79+$1); O1 ($6); } 492 493 /* ---------------------------------------------------------------------- */ 494 495 | DI 496 { B3 (0x71, 0x7b, 0xfa); } 497 498 | EI 499 { B3 (0x71, 0x7a, 0xfa); } 500 501 /* ---------------------------------------------------------------------- */ 502 503 | MULHU 504 { B3 (0xce, 0xfb, 0x01); } 505 506 | MULH 507 { B3 (0xce, 0xfb, 0x02); } 508 509 | MULU X 510 { B1 (0xd6); } 511 512 | DIVHU 513 { B3 (0xce, 0xfb, 0x03); } 514 515 /* Note that the DIVWU encoding was changed from [0xce,0xfb,0x04] to 516 [0xce,0xfb,0x0b]. Different versions of the Software Manual exist 517 with the same version number, but varying encodings. The version 518 here matches the hardware. */ 519 520 | DIVWU 521 { B3 (0xce, 0xfb, 0x0b); } 522 523 | MACHU 524 { B3 (0xce, 0xfb, 0x05); } 525 526 | MACH 527 { B3 (0xce, 0xfb, 0x06); } 528 529 /* ---------------------------------------------------------------------- */ 530 531 | HALT 532 { B2 (0x61, 0xed); } 533 534 /* ---------------------------------------------------------------------- */ 535 /* Note that opt_es is included even when it's not an option, to avoid 536 shift/reduce conflicts. The NOT_ES macro produces an error if ES: 537 is given by the user. */ 538 539 | MOV A ',' '#' EXPR 540 { B1 (0x51); O1 ($5); } 541 | MOV regb_na ',' '#' EXPR 542 { B1 (0x50); F($2, 5, 3); O1 ($5); } 543 544 | MOV sfr ',' '#' EXPR 545 { if ($2 != 0xfd) 546 { B2 (0xce, $2); O1 ($5); } 547 else 548 { B1 (0x41); O1 ($5); } 549 } 550 551 | MOV opt_es EXPR ',' '#' EXPR {NOT_ES} 552 { if (expr_is_sfr ($3)) 553 { B1 (0xce); O1 ($3); O1 ($6); } 554 else if (expr_is_saddr ($3)) 555 { B1 (0xcd); O1 ($3); O1 ($6); } 556 else 557 NOT_SFR_OR_SADDR; 558 } 559 560 | MOV '!' EXPR ',' '#' EXPR 561 { B1 (0xcf); O2 ($3); O1 ($6); rl78_linkrelax_addr16 (); } 562 563 | MOV ES ':' '!' EXPR ',' '#' EXPR 564 { B2 (0x11, 0xcf); O2 ($5); O1 ($8); } 565 566 | MOV regb_na ',' A 567 { B1 (0x70); F ($2, 5, 3); } 568 569 | MOV A ',' regb_na 570 { B1 (0x60); F ($4, 5, 3); } 571 572 | MOV opt_es EXPR ',' A {NOT_ES} 573 { if (expr_is_sfr ($3)) 574 { B1 (0x9e); O1 ($3); } 575 else if (expr_is_saddr ($3)) 576 { B1 (0x9d); O1 ($3); } 577 else 578 NOT_SFR_OR_SADDR; 579 } 580 581 | MOV A ',' opt_es '!' EXPR 582 { B1 (0x8f); O2 ($6); rl78_linkrelax_addr16 (); } 583 584 | MOV '!' EXPR ',' A 585 { B1 (0x9f); O2 ($3); rl78_linkrelax_addr16 (); } 586 587 | MOV ES ':' '!' EXPR ',' A 588 { B2 (0x11, 0x9f); O2 ($5); } 589 590 | MOV regb_na ',' opt_es '!' EXPR 591 { B1 (0xc9|reg_xbc($2)); O2 ($6); rl78_linkrelax_addr16 (); } 592 593 | MOV A ',' opt_es EXPR {NOT_ES} 594 { if (expr_is_saddr ($5)) 595 { B1 (0x8d); O1 ($5); } 596 else if (expr_is_sfr ($5)) 597 { B1 (0x8e); O1 ($5); } 598 else 599 NOT_SFR_OR_SADDR; 600 } 601 602 | MOV regb_na ',' opt_es EXPR {SA($5)} {NOT_ES} 603 { B1 (0xc8|reg_xbc($2)); O1 ($5); } 604 605 | MOV A ',' sfr 606 { B2 (0x8e, $4); } 607 608 | MOV sfr ',' regb 609 { if ($4 != 1) 610 rl78_error ("Only A allowed here"); 611 else 612 { B2 (0x9e, $2); } 613 } 614 615 | MOV sfr ',' opt_es EXPR {SA($5)} {NOT_ES} 616 { if ($2 != 0xfd) 617 rl78_error ("Only ES allowed here"); 618 else 619 { B2 (0x61, 0xb8); O1 ($5); } 620 } 621 622 | MOV A ',' opt_es '[' DE ']' 623 { B1 (0x89); } 624 625 | MOV opt_es '[' DE ']' ',' A 626 { B1 (0x99); } 627 628 | MOV opt_es '[' DE '+' EXPR ']' ',' '#' EXPR 629 { B1 (0xca); O1 ($6); O1 ($10); } 630 631 | MOV A ',' opt_es '[' DE '+' EXPR ']' 632 { B1 (0x8a); O1 ($8); } 633 634 | MOV opt_es '[' DE '+' EXPR ']' ',' A 635 { B1 (0x9a); O1 ($6); } 636 637 | MOV A ',' opt_es '[' HL ']' 638 { B1 (0x8b); } 639 640 | MOV opt_es '[' HL ']' ',' A 641 { B1 (0x9b); } 642 643 | MOV opt_es '[' HL '+' EXPR ']' ',' '#' EXPR 644 { B1 (0xcc); O1 ($6); O1 ($10); } 645 646 | MOV A ',' opt_es '[' HL '+' EXPR ']' 647 { B1 (0x8c); O1 ($8); } 648 649 | MOV opt_es '[' HL '+' EXPR ']' ',' A 650 { B1 (0x9c); O1 ($6); } 651 652 | MOV A ',' opt_es '[' HL '+' B ']' 653 { B2 (0x61, 0xc9); } 654 655 | MOV opt_es '[' HL '+' B ']' ',' A 656 { B2 (0x61, 0xd9); } 657 658 | MOV A ',' opt_es '[' HL '+' C ']' 659 { B2 (0x61, 0xe9); } 660 661 | MOV opt_es '[' HL '+' C ']' ',' A 662 { B2 (0x61, 0xf9); } 663 664 | MOV opt_es EXPR '[' B ']' ',' '#' EXPR 665 { B1 (0x19); O2 ($3); O1 ($9); } 666 667 | MOV A ',' opt_es EXPR '[' B ']' 668 { B1 (0x09); O2 ($5); } 669 670 | MOV opt_es EXPR '[' B ']' ',' A 671 { B1 (0x18); O2 ($3); } 672 673 | MOV opt_es EXPR '[' C ']' ',' '#' EXPR 674 { B1 (0x38); O2 ($3); O1 ($9); } 675 676 | MOV A ',' opt_es EXPR '[' C ']' 677 { B1 (0x29); O2 ($5); } 678 679 | MOV opt_es EXPR '[' C ']' ',' A 680 { B1 (0x28); O2 ($3); } 681 682 | MOV opt_es EXPR '[' BC ']' ',' '#' EXPR 683 { B1 (0x39); O2 ($3); O1 ($9); } 684 685 | MOV opt_es '[' BC ']' ',' '#' EXPR 686 { B3 (0x39, 0, 0); O1 ($8); } 687 688 | MOV A ',' opt_es EXPR '[' BC ']' 689 { B1 (0x49); O2 ($5); } 690 691 | MOV A ',' opt_es '[' BC ']' 692 { B3 (0x49, 0, 0); } 693 694 | MOV opt_es EXPR '[' BC ']' ',' A 695 { B1 (0x48); O2 ($3); } 696 697 | MOV opt_es '[' BC ']' ',' A 698 { B3 (0x48, 0, 0); } 699 700 | MOV opt_es '[' SP '+' EXPR ']' ',' '#' EXPR {NOT_ES} 701 { B1 (0xc8); O1 ($6); O1 ($10); } 702 703 | MOV opt_es '[' SP ']' ',' '#' EXPR {NOT_ES} 704 { B2 (0xc8, 0); O1 ($8); } 705 706 | MOV A ',' opt_es '[' SP '+' EXPR ']' {NOT_ES} 707 { B1 (0x88); O1 ($8); } 708 709 | MOV A ',' opt_es '[' SP ']' {NOT_ES} 710 { B2 (0x88, 0); } 711 712 | MOV opt_es '[' SP '+' EXPR ']' ',' A {NOT_ES} 713 { B1 (0x98); O1 ($6); } 714 715 | MOV opt_es '[' SP ']' ',' A {NOT_ES} 716 { B2 (0x98, 0); } 717 718 /* ---------------------------------------------------------------------- */ 719 720 | mov1 CY ',' EXPR '.' EXPR 721 { if (expr_is_saddr ($4)) 722 { B2 (0x71, 0x04); FE ($6, 9, 3); O1 ($4); } 723 else if (expr_is_sfr ($4)) 724 { B2 (0x71, 0x0c); FE ($6, 9, 3); O1 ($4); } 725 else 726 NOT_SFR_OR_SADDR; 727 } 728 729 | mov1 CY ',' A '.' EXPR 730 { B2 (0x71, 0x8c); FE ($6, 9, 3); } 731 732 | mov1 CY ',' sfr '.' EXPR 733 { B3 (0x71, 0x0c, $4); FE ($6, 9, 3); } 734 735 | mov1 CY ',' opt_es '[' HL ']' '.' EXPR 736 { B2 (0x71, 0x84); FE ($9, 9, 3); } 737 738 | mov1 EXPR '.' EXPR ',' CY 739 { if (expr_is_saddr ($2)) 740 { B2 (0x71, 0x01); FE ($4, 9, 3); O1 ($2); } 741 else if (expr_is_sfr ($2)) 742 { B2 (0x71, 0x09); FE ($4, 9, 3); O1 ($2); } 743 else 744 NOT_SFR_OR_SADDR; 745 } 746 747 | mov1 A '.' EXPR ',' CY 748 { B2 (0x71, 0x89); FE ($4, 9, 3); } 749 750 | mov1 sfr '.' EXPR ',' CY 751 { B3 (0x71, 0x09, $2); FE ($4, 9, 3); } 752 753 | mov1 opt_es '[' HL ']' '.' EXPR ',' CY 754 { B2 (0x71, 0x81); FE ($7, 9, 3); } 755 756 /* ---------------------------------------------------------------------- */ 757 758 | MOVS opt_es '[' HL '+' EXPR ']' ',' X 759 { B2 (0x61, 0xce); O1 ($6); } 760 761 /* ---------------------------------------------------------------------- */ 762 763 | MOVW AX ',' '#' EXPR 764 { B1 (0x30); O2 ($5); } 765 766 | MOVW regw_na ',' '#' EXPR 767 { B1 (0x30); F ($2, 5, 2); O2 ($5); } 768 769 | MOVW opt_es EXPR ',' '#' EXPR {NOT_ES} 770 { if (expr_is_saddr ($3)) 771 { B1 (0xc9); O1 ($3); O2 ($6); } 772 else if (expr_is_sfr ($3)) 773 { B1 (0xcb); O1 ($3); O2 ($6); } 774 else 775 NOT_SFR_OR_SADDR; 776 } 777 778 | MOVW AX ',' opt_es EXPR {NOT_ES} 779 { if (expr_is_saddr ($5)) 780 { B1 (0xad); O1 ($5); WA($5); } 781 else if (expr_is_sfr ($5)) 782 { B1 (0xae); O1 ($5); WA($5); } 783 else 784 NOT_SFR_OR_SADDR; 785 } 786 787 | MOVW opt_es EXPR ',' AX {NOT_ES} 788 { if (expr_is_saddr ($3)) 789 { B1 (0xbd); O1 ($3); WA($3); } 790 else if (expr_is_sfr ($3)) 791 { B1 (0xbe); O1 ($3); WA($3); } 792 else 793 NOT_SFR_OR_SADDR; 794 } 795 796 | MOVW AX ',' regw_na 797 { B1 (0x11); F ($4, 5, 2); } 798 799 | MOVW regw_na ',' AX 800 { B1 (0x10); F ($2, 5, 2); } 801 802 | MOVW AX ',' opt_es '!' EXPR 803 { B1 (0xaf); O2 ($6); WA($6); rl78_linkrelax_addr16 (); } 804 805 | MOVW opt_es '!' EXPR ',' AX 806 { B1 (0xbf); O2 ($4); WA($4); rl78_linkrelax_addr16 (); } 807 808 | MOVW AX ',' opt_es '[' DE ']' 809 { B1 (0xa9); } 810 811 | MOVW opt_es '[' DE ']' ',' AX 812 { B1 (0xb9); } 813 814 | MOVW AX ',' opt_es '[' DE '+' EXPR ']' 815 { B1 (0xaa); O1 ($8); } 816 817 | MOVW opt_es '[' DE '+' EXPR ']' ',' AX 818 { B1 (0xba); O1 ($6); } 819 820 | MOVW AX ',' opt_es '[' HL ']' 821 { B1 (0xab); } 822 823 | MOVW opt_es '[' HL ']' ',' AX 824 { B1 (0xbb); } 825 826 | MOVW AX ',' opt_es '[' HL '+' EXPR ']' 827 { B1 (0xac); O1 ($8); } 828 829 | MOVW opt_es '[' HL '+' EXPR ']' ',' AX 830 { B1 (0xbc); O1 ($6); } 831 832 | MOVW AX ',' opt_es EXPR '[' B ']' 833 { B1 (0x59); O2 ($5); } 834 835 | MOVW opt_es EXPR '[' B ']' ',' AX 836 { B1 (0x58); O2 ($3); } 837 838 | MOVW AX ',' opt_es EXPR '[' C ']' 839 { B1 (0x69); O2 ($5); } 840 841 | MOVW opt_es EXPR '[' C ']' ',' AX 842 { B1 (0x68); O2 ($3); } 843 844 | MOVW AX ',' opt_es EXPR '[' BC ']' 845 { B1 (0x79); O2 ($5); } 846 847 | MOVW AX ',' opt_es '[' BC ']' 848 { B3 (0x79, 0, 0); } 849 850 | MOVW opt_es EXPR '[' BC ']' ',' AX 851 { B1 (0x78); O2 ($3); } 852 853 | MOVW opt_es '[' BC ']' ',' AX 854 { B3 (0x78, 0, 0); } 855 856 | MOVW AX ',' opt_es '[' SP '+' EXPR ']' {NOT_ES} 857 { B1 (0xa8); O1 ($8); WA($8);} 858 859 | MOVW AX ',' opt_es '[' SP ']' {NOT_ES} 860 { B2 (0xa8, 0); } 861 862 | MOVW opt_es '[' SP '+' EXPR ']' ',' AX {NOT_ES} 863 { B1 (0xb8); O1 ($6); WA($6); } 864 865 | MOVW opt_es '[' SP ']' ',' AX {NOT_ES} 866 { B2 (0xb8, 0); } 867 868 | MOVW regw_na ',' EXPR {SA($4)} 869 { B1 (0xca); F ($2, 2, 2); O1 ($4); WA($4); } 870 871 | MOVW regw_na ',' opt_es '!' EXPR 872 { B1 (0xcb); F ($2, 2, 2); O2 ($6); WA($6); rl78_linkrelax_addr16 (); } 873 874 | MOVW SP ',' '#' EXPR 875 { B2 (0xcb, 0xf8); O2 ($5); } 876 877 | MOVW SP ',' AX 878 { B2 (0xbe, 0xf8); } 879 880 | MOVW AX ',' SP 881 { B2 (0xae, 0xf8); } 882 883 | MOVW regw_na ',' SP 884 { B3 (0xcb, 0xf8, 0xff); F ($2, 2, 2); } 885 886 /* ---------------------------------------------------------------------- */ 887 888 | NOP 889 { B1 (0x00); } 890 891 /* ---------------------------------------------------------------------- */ 892 893 | NOT1 CY 894 { B2 (0x71, 0xc0); } 895 896 /* ---------------------------------------------------------------------- */ 897 898 | POP regw 899 { B1 (0xc0); F ($2, 5, 2); } 900 901 | POP PSW 902 { B2 (0x61, 0xcd); }; 903 904 | PUSH regw 905 { B1 (0xc1); F ($2, 5, 2); } 906 907 | PUSH PSW 908 { B2 (0x61, 0xdd); }; 909 910 /* ---------------------------------------------------------------------- */ 911 912 | RET 913 { B1 (0xd7); } 914 915 | RETI 916 { B2 (0x61, 0xfc); } 917 918 | RETB 919 { B2 (0x61, 0xec); } 920 921 /* ---------------------------------------------------------------------- */ 922 923 | ROL A ',' EXPR 924 { if (check_expr_is_const ($4, 1, 1)) 925 { B2 (0x61, 0xeb); } 926 } 927 928 | ROLC A ',' EXPR 929 { if (check_expr_is_const ($4, 1, 1)) 930 { B2 (0x61, 0xdc); } 931 } 932 933 | ROLWC AX ',' EXPR 934 { if (check_expr_is_const ($4, 1, 1)) 935 { B2 (0x61, 0xee); } 936 } 937 938 | ROLWC BC ',' EXPR 939 { if (check_expr_is_const ($4, 1, 1)) 940 { B2 (0x61, 0xfe); } 941 } 942 943 | ROR A ',' EXPR 944 { if (check_expr_is_const ($4, 1, 1)) 945 { B2 (0x61, 0xdb); } 946 } 947 948 | RORC A ',' EXPR 949 { if (check_expr_is_const ($4, 1, 1)) 950 { B2 (0x61, 0xfb);} 951 } 952 953 /* ---------------------------------------------------------------------- */ 954 955 | SAR A ',' EXPR 956 { if (check_expr_is_const ($4, 1, 7)) 957 { B2 (0x31, 0x0b); FE ($4, 9, 3); } 958 } 959 960 | SARW AX ',' EXPR 961 { if (check_expr_is_const ($4, 1, 15)) 962 { B2 (0x31, 0x0f); FE ($4, 8, 4); } 963 } 964 965 /* ---------------------------------------------------------------------- */ 966 967 | SEL RB0 968 { B2 (0x61, 0xcf); } 969 970 | SEL RB1 971 { B2 (0x61, 0xdf); } 972 973 | SEL RB2 974 { B2 (0x61, 0xef); } 975 976 | SEL RB3 977 { B2 (0x61, 0xff); } 978 979 /* ---------------------------------------------------------------------- */ 980 981 | SHL A ',' EXPR 982 { if (check_expr_is_const ($4, 1, 7)) 983 { B2 (0x31, 0x09); FE ($4, 9, 3); } 984 } 985 986 | SHL B ',' EXPR 987 { if (check_expr_is_const ($4, 1, 7)) 988 { B2 (0x31, 0x08); FE ($4, 9, 3); } 989 } 990 991 | SHL C ',' EXPR 992 { if (check_expr_is_const ($4, 1, 7)) 993 { B2 (0x31, 0x07); FE ($4, 9, 3); } 994 } 995 996 | SHLW AX ',' EXPR 997 { if (check_expr_is_const ($4, 1, 15)) 998 { B2 (0x31, 0x0d); FE ($4, 8, 4); } 999 } 1000 1001 | SHLW BC ',' EXPR 1002 { if (check_expr_is_const ($4, 1, 15)) 1003 { B2 (0x31, 0x0c); FE ($4, 8, 4); } 1004 } 1005 1006 /* ---------------------------------------------------------------------- */ 1007 1008 | SHR A ',' EXPR 1009 { if (check_expr_is_const ($4, 1, 7)) 1010 { B2 (0x31, 0x0a); FE ($4, 9, 3); } 1011 } 1012 1013 | SHRW AX ',' EXPR 1014 { if (check_expr_is_const ($4, 1, 15)) 1015 { B2 (0x31, 0x0e); FE ($4, 8, 4); } 1016 } 1017 1018 /* ---------------------------------------------------------------------- */ 1019 1020 | SKC 1021 { B2 (0x61, 0xc8); rl78_linkrelax_branch (); } 1022 1023 | SKH 1024 { B2 (0x61, 0xe3); rl78_linkrelax_branch (); } 1025 1026 | SKNC 1027 { B2 (0x61, 0xd8); rl78_linkrelax_branch (); } 1028 1029 | SKNH 1030 { B2 (0x61, 0xf3); rl78_linkrelax_branch (); } 1031 1032 | SKNZ 1033 { B2 (0x61, 0xf8); rl78_linkrelax_branch (); } 1034 1035 | SKZ 1036 { B2 (0x61, 0xe8); rl78_linkrelax_branch (); } 1037 1038 /* ---------------------------------------------------------------------- */ 1039 1040 | STOP 1041 { B2 (0x61, 0xfd); } 1042 1043 /* ---------------------------------------------------------------------- */ 1044 1045 | XCH A ',' regb_na 1046 { if ($4 == 0) /* X */ 1047 { B1 (0x08); } 1048 else 1049 { B2 (0x61, 0x88); F ($4, 13, 3); } 1050 } 1051 1052 | XCH A ',' opt_es '!' EXPR 1053 { B2 (0x61, 0xaa); O2 ($6); rl78_linkrelax_addr16 (); } 1054 1055 | XCH A ',' opt_es '[' DE ']' 1056 { B2 (0x61, 0xae); } 1057 1058 | XCH A ',' opt_es '[' DE '+' EXPR ']' 1059 { B2 (0x61, 0xaf); O1 ($8); } 1060 1061 | XCH A ',' opt_es '[' HL ']' 1062 { B2 (0x61, 0xac); } 1063 1064 | XCH A ',' opt_es '[' HL '+' EXPR ']' 1065 { B2 (0x61, 0xad); O1 ($8); } 1066 1067 | XCH A ',' opt_es '[' HL '+' B ']' 1068 { B2 (0x61, 0xb9); } 1069 1070 | XCH A ',' opt_es '[' HL '+' C ']' 1071 { B2 (0x61, 0xa9); } 1072 1073 | XCH A ',' EXPR 1074 { if (expr_is_sfr ($4)) 1075 { B2 (0x61, 0xab); O1 ($4); } 1076 else if (expr_is_saddr ($4)) 1077 { B2 (0x61, 0xa8); O1 ($4); } 1078 else 1079 NOT_SFR_OR_SADDR; 1080 } 1081 1082 /* ---------------------------------------------------------------------- */ 1083 1084 | XCHW AX ',' regw_na 1085 { B1 (0x31); F ($4, 5, 2); } 1086 1087 /* ---------------------------------------------------------------------- */ 1088 1089 ; /* end of statement */ 1090 1091 /* ---------------------------------------------------------------------- */ 1092 1093 opt_es : /* nothing */ 1094 | ES ':' 1095 { rl78_prefix (0x11); } 1096 ; 1097 1098 regb : X { $$ = 0; } 1099 | A { $$ = 1; } 1100 | C { $$ = 2; } 1101 | B { $$ = 3; } 1102 | E { $$ = 4; } 1103 | D { $$ = 5; } 1104 | L { $$ = 6; } 1105 | H { $$ = 7; } 1106 ; 1107 1108 regb_na : X { $$ = 0; } 1109 | C { $$ = 2; } 1110 | B { $$ = 3; } 1111 | E { $$ = 4; } 1112 | D { $$ = 5; } 1113 | L { $$ = 6; } 1114 | H { $$ = 7; } 1115 ; 1116 1117 regw : AX { $$ = 0; } 1118 | BC { $$ = 1; } 1119 | DE { $$ = 2; } 1120 | HL { $$ = 3; } 1121 ; 1122 1123 regw_na : BC { $$ = 1; } 1124 | DE { $$ = 2; } 1125 | HL { $$ = 3; } 1126 ; 1127 1128 sfr : SPL { $$ = 0xf8; } 1129 | SPH { $$ = 0xf9; } 1130 | PSW { $$ = 0xfa; } 1131 | CS { $$ = 0xfc; } 1132 | ES { $$ = 0xfd; } 1133 | PMC { $$ = 0xfe; } 1134 | MEM { $$ = 0xff; } 1135 ; 1136 1137 /* ---------------------------------------------------------------------- */ 1138 /* Shortcuts for groups of opcodes with common encodings. */ 1139 1140 addsub : ADD { $$ = 0x00; } 1141 | ADDC { $$ = 0x10; } 1142 | SUB { $$ = 0x20; } 1143 | SUBC { $$ = 0x30; } 1144 | CMP { $$ = 0x40; } 1145 | AND_ { $$ = 0x50; } 1146 | OR { $$ = 0x60; } 1147 | XOR { $$ = 0x70; } 1148 ; 1149 1150 addsubw : ADDW { $$ = 0x00; } 1151 | SUBW { $$ = 0x20; } 1152 | CMPW { $$ = 0x40; } 1153 ; 1154 1155 andor1 : AND1 { $$ = 0x05; rl78_bit_insn = 1; } 1156 | OR1 { $$ = 0x06; rl78_bit_insn = 1; } 1157 | XOR1 { $$ = 0x07; rl78_bit_insn = 1; } 1158 ; 1159 1160 bt_bf : BT { $$ = 0x02; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); } 1161 | BF { $$ = 0x04; rl78_bit_insn = 1; rl78_relax (RL78_RELAX_BRANCH, 0); } 1162 | BTCLR { $$ = 0x00; rl78_bit_insn = 1; } 1163 ; 1164 1165 setclr1 : SET1 { $$ = 0; rl78_bit_insn = 1; } 1166 | CLR1 { $$ = 1; rl78_bit_insn = 1; } 1167 ; 1168 1169 oneclrb : ONEB { $$ = 0x00; } 1170 | CLRB { $$ = 0x10; } 1171 ; 1172 1173 oneclrw : ONEW { $$ = 0x00; } 1174 | CLRW { $$ = 0x10; } 1175 ; 1176 1177 incdec : INC { $$ = 0x00; } 1178 | DEC { $$ = 0x10; } 1179 ; 1180 1181 incdecw : INCW { $$ = 0x00; } 1182 | DECW { $$ = 0x10; } 1183 ; 1184 1185 mov1 : MOV1 { rl78_bit_insn = 1; } 1186 ; 1187 1188 %% 1189 /* ====================================================================== */ 1190 1191 static struct 1192 { 1193 const char * string; 1194 int token; 1195 int val; 1196 } 1197 token_table[] = 1198 { 1199 { "r0", X, 0 }, 1200 { "r1", A, 1 }, 1201 { "r2", C, 2 }, 1202 { "r3", B, 3 }, 1203 { "r4", E, 4 }, 1204 { "r5", D, 5 }, 1205 { "r6", L, 6 }, 1206 { "r7", H, 7 }, 1207 { "x", X, 0 }, 1208 { "a", A, 1 }, 1209 { "c", C, 2 }, 1210 { "b", B, 3 }, 1211 { "e", E, 4 }, 1212 { "d", D, 5 }, 1213 { "l", L, 6 }, 1214 { "h", H, 7 }, 1215 1216 { "rp0", AX, 0 }, 1217 { "rp1", BC, 1 }, 1218 { "rp2", DE, 2 }, 1219 { "rp3", HL, 3 }, 1220 { "ax", AX, 0 }, 1221 { "bc", BC, 1 }, 1222 { "de", DE, 2 }, 1223 { "hl", HL, 3 }, 1224 1225 { "RB0", RB0, 0 }, 1226 { "RB1", RB1, 1 }, 1227 { "RB2", RB2, 2 }, 1228 { "RB3", RB3, 3 }, 1229 1230 { "sp", SP, 0 }, 1231 { "cy", CY, 0 }, 1232 1233 { "spl", SPL, 0xf8 }, 1234 { "sph", SPH, 0xf9 }, 1235 { "psw", PSW, 0xfa }, 1236 { "cs", CS, 0xfc }, 1237 { "es", ES, 0xfd }, 1238 { "pmc", PMC, 0xfe }, 1239 { "mem", MEM, 0xff }, 1240 1241 { ".s", DOT_S, 0 }, 1242 { ".b", DOT_B, 0 }, 1243 { ".w", DOT_W, 0 }, 1244 { ".l", DOT_L, 0 }, 1245 { ".a", DOT_A , 0}, 1246 { ".ub", DOT_UB, 0 }, 1247 { ".uw", DOT_UW , 0}, 1248 1249 { "c", FLAG, 0 }, 1250 { "z", FLAG, 1 }, 1251 { "s", FLAG, 2 }, 1252 { "o", FLAG, 3 }, 1253 { "i", FLAG, 8 }, 1254 { "u", FLAG, 9 }, 1255 1256 #define OPC(x) { #x, x, IS_OPCODE } 1257 1258 OPC(ADD), 1259 OPC(ADDC), 1260 OPC(ADDW), 1261 { "and", AND_, IS_OPCODE }, 1262 OPC(AND1), 1263 OPC(BC), 1264 OPC(BF), 1265 OPC(BH), 1266 OPC(BNC), 1267 OPC(BNH), 1268 OPC(BNZ), 1269 OPC(BR), 1270 OPC(BRK), 1271 OPC(BRK1), 1272 OPC(BT), 1273 OPC(BTCLR), 1274 OPC(BZ), 1275 OPC(CALL), 1276 OPC(CALLT), 1277 OPC(CLR1), 1278 OPC(CLRB), 1279 OPC(CLRW), 1280 OPC(CMP), 1281 OPC(CMP0), 1282 OPC(CMPS), 1283 OPC(CMPW), 1284 OPC(DEC), 1285 OPC(DECW), 1286 OPC(DI), 1287 OPC(DIVHU), 1288 OPC(DIVWU), 1289 OPC(EI), 1290 OPC(HALT), 1291 OPC(INC), 1292 OPC(INCW), 1293 OPC(MACH), 1294 OPC(MACHU), 1295 OPC(MOV), 1296 OPC(MOV1), 1297 OPC(MOVS), 1298 OPC(MOVW), 1299 OPC(MULH), 1300 OPC(MULHU), 1301 OPC(MULU), 1302 OPC(NOP), 1303 OPC(NOT1), 1304 OPC(ONEB), 1305 OPC(ONEW), 1306 OPC(OR), 1307 OPC(OR1), 1308 OPC(POP), 1309 OPC(PUSH), 1310 OPC(RET), 1311 OPC(RETI), 1312 OPC(RETB), 1313 OPC(ROL), 1314 OPC(ROLC), 1315 OPC(ROLWC), 1316 OPC(ROR), 1317 OPC(RORC), 1318 OPC(SAR), 1319 OPC(SARW), 1320 OPC(SEL), 1321 OPC(SET1), 1322 OPC(SHL), 1323 OPC(SHLW), 1324 OPC(SHR), 1325 OPC(SHRW), 1326 OPC(SKC), 1327 OPC(SKH), 1328 OPC(SKNC), 1329 OPC(SKNH), 1330 OPC(SKNZ), 1331 OPC(SKZ), 1332 OPC(STOP), 1333 OPC(SUB), 1334 OPC(SUBC), 1335 OPC(SUBW), 1336 OPC(XCH), 1337 OPC(XCHW), 1338 OPC(XOR), 1339 OPC(XOR1), 1340 }; 1341 1342 #define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0])) 1343 1344 void 1345 rl78_lex_init (char * beginning, char * ending) 1346 { 1347 rl78_init_start = beginning; 1348 rl78_lex_start = beginning; 1349 rl78_lex_end = ending; 1350 rl78_in_brackets = 0; 1351 rl78_last_token = 0; 1352 1353 rl78_bit_insn = 0; 1354 1355 setbuf (stdout, 0); 1356 } 1357 1358 /* Return a pointer to the '.' in a bit index expression (like 1359 foo.5), or NULL if none is found. */ 1360 static char * 1361 find_bit_index (char *tok) 1362 { 1363 char *last_dot = NULL; 1364 char *last_digit = NULL; 1365 while (*tok && *tok != ',') 1366 { 1367 if (*tok == '.') 1368 { 1369 last_dot = tok; 1370 last_digit = NULL; 1371 } 1372 else if (*tok >= '0' && *tok <= '7' 1373 && last_dot != NULL 1374 && last_digit == NULL) 1375 { 1376 last_digit = tok; 1377 } 1378 else if (ISSPACE (*tok)) 1379 { 1380 /* skip */ 1381 } 1382 else 1383 { 1384 last_dot = NULL; 1385 last_digit = NULL; 1386 } 1387 tok ++; 1388 } 1389 if (last_dot != NULL 1390 && last_digit != NULL) 1391 return last_dot; 1392 return NULL; 1393 } 1394 1395 static int 1396 rl78_lex (void) 1397 { 1398 /*unsigned int ci;*/ 1399 char * save_input_pointer; 1400 char * bit = NULL; 1401 1402 while (ISSPACE (*rl78_lex_start) 1403 && rl78_lex_start != rl78_lex_end) 1404 rl78_lex_start ++; 1405 1406 rl78_last_exp_start = rl78_lex_start; 1407 1408 if (rl78_lex_start == rl78_lex_end) 1409 return 0; 1410 1411 if (ISALPHA (*rl78_lex_start) 1412 || (*rl78_lex_start == '.' && ISALPHA (rl78_lex_start[1]))) 1413 { 1414 unsigned int i; 1415 char * e; 1416 char save; 1417 1418 for (e = rl78_lex_start + 1; 1419 e < rl78_lex_end && ISALNUM (*e); 1420 e ++) 1421 ; 1422 save = *e; 1423 *e = 0; 1424 1425 for (i = 0; i < NUM_TOKENS; i++) 1426 if (strcasecmp (rl78_lex_start, token_table[i].string) == 0 1427 && !(token_table[i].val == IS_OPCODE && rl78_last_token != 0) 1428 && !(token_table[i].token == FLAG && !need_flag)) 1429 { 1430 rl78_lval.regno = token_table[i].val; 1431 *e = save; 1432 rl78_lex_start = e; 1433 rl78_last_token = token_table[i].token; 1434 return token_table[i].token; 1435 } 1436 *e = save; 1437 } 1438 1439 if (rl78_last_token == 0) 1440 { 1441 rl78_last_token = UNKNOWN_OPCODE; 1442 return UNKNOWN_OPCODE; 1443 } 1444 1445 if (rl78_last_token == UNKNOWN_OPCODE) 1446 return 0; 1447 1448 if (*rl78_lex_start == '[') 1449 rl78_in_brackets = 1; 1450 if (*rl78_lex_start == ']') 1451 rl78_in_brackets = 0; 1452 1453 /* '.' is funny - the syntax includes it for bitfields, but only for 1454 bitfields. We check for it specially so we can allow labels 1455 with '.' in them. */ 1456 1457 if (rl78_bit_insn 1458 && *rl78_lex_start == '.' 1459 && find_bit_index (rl78_lex_start) == rl78_lex_start) 1460 { 1461 rl78_last_token = *rl78_lex_start; 1462 return *rl78_lex_start ++; 1463 } 1464 1465 if ((rl78_in_brackets && *rl78_lex_start == '+') 1466 || strchr ("[],#!$:", *rl78_lex_start)) 1467 { 1468 rl78_last_token = *rl78_lex_start; 1469 return *rl78_lex_start ++; 1470 } 1471 1472 /* Again, '.' is funny. Look for '.<digit>' at the end of the line 1473 or before a comma, which is a bitfield, not an expression. */ 1474 1475 if (rl78_bit_insn) 1476 { 1477 bit = find_bit_index (rl78_lex_start); 1478 if (bit) 1479 *bit = 0; 1480 else 1481 bit = NULL; 1482 } 1483 1484 save_input_pointer = input_line_pointer; 1485 input_line_pointer = rl78_lex_start; 1486 rl78_lval.exp.X_md = 0; 1487 expression (&rl78_lval.exp); 1488 1489 if (bit) 1490 *bit = '.'; 1491 1492 rl78_lex_start = input_line_pointer; 1493 input_line_pointer = save_input_pointer; 1494 rl78_last_token = EXPR; 1495 return EXPR; 1496 } 1497 1498 int 1499 rl78_error (const char * str) 1500 { 1501 int len; 1502 1503 len = rl78_last_exp_start - rl78_init_start; 1504 1505 as_bad ("%s", rl78_init_start); 1506 as_bad ("%*s^ %s", len, "", str); 1507 return 0; 1508 } 1509 1510 static int 1511 expr_is_sfr (expressionS exp) 1512 { 1513 unsigned long v; 1514 1515 if (exp.X_op != O_constant) 1516 return 0; 1517 1518 v = exp.X_add_number; 1519 if (0xFFF00 <= v && v <= 0xFFFFF) 1520 return 1; 1521 return 0; 1522 } 1523 1524 static int 1525 expr_is_saddr (expressionS exp) 1526 { 1527 unsigned long v; 1528 1529 if (exp.X_op != O_constant) 1530 return 0; 1531 1532 v = exp.X_add_number; 1533 if (0xFFE20 <= v && v <= 0xFFF1F) 1534 return 1; 1535 return 0; 1536 } 1537 1538 static int 1539 expr_is_word_aligned (expressionS exp) 1540 { 1541 unsigned long v; 1542 1543 if (exp.X_op != O_constant) 1544 return 1; 1545 1546 v = exp.X_add_number; 1547 if (v & 1) 1548 return 0; 1549 return 1; 1550 1551 } 1552 1553 static void 1554 check_expr_is_bit_index (expressionS exp) 1555 { 1556 int val; 1557 1558 if (exp.X_op != O_constant) 1559 { 1560 rl78_error (_("bit index must be a constant")); 1561 return; 1562 } 1563 val = exp.X_add_number; 1564 1565 if (val < 0 || val > 7) 1566 rl78_error (_("rtsd size must be 0..7")); 1567 } 1568 1569 static int 1570 exp_val (expressionS exp) 1571 { 1572 if (exp.X_op != O_constant) 1573 { 1574 rl78_error (_("constant expected")); 1575 return 0; 1576 } 1577 return exp.X_add_number; 1578 } 1579 1580 static int 1581 check_expr_is_const (expressionS e, int vmin, int vmax) 1582 { 1583 static char buf[100]; 1584 if (e.X_op != O_constant 1585 || e.X_add_number < vmin 1586 || e.X_add_number > vmax) 1587 { 1588 if (vmin == vmax) 1589 sprintf (buf, "%d expected here", vmin); 1590 else 1591 sprintf (buf, "%d..%d expected here", vmin, vmax); 1592 rl78_error(buf); 1593 return 0; 1594 } 1595 return 1; 1596 } 1597 1598 1599