rx-parse.y revision 1.1.1.6
1/* rx-parse.y Renesas RX parser 2 Copyright (C) 2008-2020 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 "rx-defs.h" 25 26static int rx_lex (void); 27 28#define COND_EQ 0 29#define COND_NE 1 30 31#define MEMEX 0x06 32 33#define BSIZE 0 34#define WSIZE 1 35#define LSIZE 2 36#define DSIZE 3 37 38/* .sb .sw .l .uw */ 39static int sizemap[] = { BSIZE, WSIZE, LSIZE, WSIZE }; 40 41/* Ok, here are the rules for using these macros... 42 43 B*() is used to specify the base opcode bytes. Fields to be filled 44 in later, leave zero. Call this first. 45 46 F() and FE() are used to fill in fields within the base opcode bytes. You MUST 47 call B*() before any F() or FE(). 48 49 [UN]*O*(), PC*() appends operands to the end of the opcode. You 50 must call P() and B*() before any of these, so that the fixups 51 have the right byte location. 52 O = signed, UO = unsigned, NO = negated, PC = pcrel 53 54 IMM() adds an immediate and fills in the field for it. 55 NIMM() same, but negates the immediate. 56 NBIMM() same, but negates the immediate, for sbb. 57 DSP() adds a displacement, and fills in the field for it. 58 59 Note that order is significant for the O, IMM, and DSP macros, as 60 they append their data to the operand buffer in the order that you 61 call them. 62 63 Use "disp" for displacements whenever possible; this handles the 64 "0" case properly. */ 65 66#define B1(b1) rx_base1 (b1) 67#define B2(b1, b2) rx_base2 (b1, b2) 68#define B3(b1, b2, b3) rx_base3 (b1, b2, b3) 69#define B4(b1, b2, b3, b4) rx_base4 (b1, b2, b3, b4) 70 71/* POS is bits from the MSB of the first byte to the LSB of the last byte. */ 72#define F(val,pos,sz) rx_field (val, pos, sz) 73#define FE(exp,pos,sz) rx_field (exp_val (exp), pos, sz); 74 75#define O1(v) rx_op (v, 1, RXREL_SIGNED); rx_range (v, -128, 255) 76#define O2(v) rx_op (v, 2, RXREL_SIGNED); rx_range (v, -32768, 65536) 77#define O3(v) rx_op (v, 3, RXREL_SIGNED); rx_range (v, -8388608, 16777216) 78#define O4(v) rx_op (v, 4, RXREL_SIGNED) 79 80#define UO1(v) rx_op (v, 1, RXREL_UNSIGNED); rx_range (v, 0, 255) 81#define UO2(v) rx_op (v, 2, RXREL_UNSIGNED); rx_range (v, 0, 65536) 82#define UO3(v) rx_op (v, 3, RXREL_UNSIGNED); rx_range (v, 0, 16777216) 83#define UO4(v) rx_op (v, 4, RXREL_UNSIGNED) 84 85#define NO1(v) rx_op (v, 1, RXREL_NEGATIVE) 86#define NO2(v) rx_op (v, 2, RXREL_NEGATIVE) 87#define NO3(v) rx_op (v, 3, RXREL_NEGATIVE) 88#define NO4(v) rx_op (v, 4, RXREL_NEGATIVE) 89 90#define PC1(v) rx_op (v, 1, RXREL_PCREL) 91#define PC2(v) rx_op (v, 2, RXREL_PCREL) 92#define PC3(v) rx_op (v, 3, RXREL_PCREL) 93 94#define POST(v) rx_post (v) 95 96#define IMM_(v,pos,size) F (immediate (v, RXREL_SIGNED, pos, size), pos, 2); \ 97 if (v.X_op != O_constant && v.X_op != O_big) rx_linkrelax_imm (pos) 98#define IMM(v,pos) IMM_ (v, pos, 32) 99#define IMMW(v,pos) IMM_ (v, pos, 16); rx_range (v, -32768, 65536) 100#define IMMB(v,pos) IMM_ (v, pos, 8); rx_range (v, -128, 255) 101#define NIMM(v,pos) F (immediate (v, RXREL_NEGATIVE, pos, 32), pos, 2) 102#define NBIMM(v,pos) F (immediate (v, RXREL_NEGATIVE_BORROW, pos, 32), pos, 2) 103#define DSP(v,pos,msz) if (!v.X_md) rx_relax (RX_RELAX_DISP, pos); \ 104 else rx_linkrelax_dsp (pos); \ 105 F (displacement (v, msz), pos, 2) 106 107#define id24(a,b2,b3) B3 (0xfb + a, b2, b3) 108 109static void rx_check_float_support (void); 110static int rx_intop (expressionS, int, int); 111static int rx_uintop (expressionS, int); 112static int rx_disp3op (expressionS); 113static int rx_disp5op (expressionS *, int); 114static int rx_disp5op0 (expressionS *, int); 115static int exp_val (expressionS exp); 116static expressionS zero_expr (void); 117static int immediate (expressionS, int, int, int); 118static int displacement (expressionS, int); 119static void rtsd_immediate (expressionS); 120static void rx_range (expressionS, int, int); 121static void rx_check_v2 (void); 122static void rx_check_v3 (void); 123static void rx_check_dfpu (void); 124 125static int need_flag = 0; 126static int rx_in_brackets = 0; 127static int rx_last_token = 0; 128static char * rx_init_start; 129static char * rx_last_exp_start = 0; 130static int sub_op; 131static int sub_op2; 132 133#define YYDEBUG 1 134#define YYERROR_VERBOSE 1 135 136%} 137 138%name-prefix="rx_" 139 140%union { 141 int regno; 142 expressionS exp; 143} 144 145%type <regno> REG FLAG CREG BCND BMCND SCCND ACC DREG DREGH DREGL DCREG DCMP 146%type <regno> flag bwl bw memex 147%type <exp> EXPR disp 148 149%token REG FLAG CREG ACC DREG DREGH DREGL DCREG 150 151%token EXPR UNKNOWN_OPCODE IS_OPCODE 152 153%token DOT_S DOT_B DOT_W DOT_L DOT_A DOT_UB DOT_UW DOT_D 154 155%token ABS ADC ADD AND_ 156%token BCLR BCND BFMOV BFMOVZ BMCND BNOT BRA BRK BSET BSR BTST 157%token CLRPSW CMP 158%token DABS DADD DBT DCMP DDIV DIV DIVU DMOV DMUL DNEG 159%token DPOPM DPUSHM DROUND DSQRT DSUB DTOF DTOI DTOU 160%token EDIV EDIVU EMACA EMSBA EMUL EMULA EMULU 161%token FADD FCMP FDIV FMUL FREIT FSUB FSQRT FTOD FTOI FTOU 162%token INT ITOD ITOF 163%token JMP JSR 164%token MACHI MACLH MACLO MAX MIN MOV MOVCO MOVLI MOVU MSBHI MSBLH MSBLO MUL 165%token MULHI MULLH MULLO MULU MVFACHI MVFACGU MVFACMI MVFACLO MVFC MVFDC 166%token MVFDR MVTACGU MVTACHI MVTACLO MVTC MVTDC MVTIPL 167%token NEG NOP NOT 168%token OR 169%token POP POPC POPM PUSH PUSHA PUSHC PUSHM 170%token RACL RACW RDACL RDACW REIT REVL REVW RMPA ROLC RORC ROTL ROTR ROUND 171%token RSTR RTE RTFI RTS RTSD 172%token SAT SATR SAVE SBB SCCND SCMPU SETPSW SHAR SHLL SHLR SMOVB SMOVF 173%token SMOVU SSTR STNZ STOP STZ SUB SUNTIL SWHILE 174%token TST 175%token UTOD UTOF 176%token WAIT 177%token XCHG XOR 178 179%% 180/* ====================================================================== */ 181 182statement : 183 184 UNKNOWN_OPCODE 185 { as_bad (_("Unknown opcode: %s"), rx_init_start); } 186 187/* ---------------------------------------------------------------------- */ 188 189 | BRK 190 { B1 (0x00); } 191 192 | DBT 193 { B1 (0x01); } 194 195 | RTS 196 { B1 (0x02); } 197 198 | NOP 199 { B1 (0x03); } 200 201/* ---------------------------------------------------------------------- */ 202 203 | BRA EXPR 204 { if (rx_disp3op ($2)) 205 { B1 (0x08); rx_disp3 ($2, 5); } 206 else if (rx_intop ($2, 8, 8)) 207 { B1 (0x2e); PC1 ($2); } 208 else if (rx_intop ($2, 16, 16)) 209 { B1 (0x38); PC2 ($2); } 210 else if (rx_intop ($2, 24, 24)) 211 { B1 (0x04); PC3 ($2); } 212 else 213 { rx_relax (RX_RELAX_BRANCH, 0); 214 rx_linkrelax_branch (); 215 /* We'll convert this to a longer one later if needed. */ 216 B1 (0x08); rx_disp3 ($2, 5); } } 217 218 | BRA DOT_A EXPR 219 { B1 (0x04); PC3 ($3); } 220 221 | BRA DOT_S EXPR 222 { B1 (0x08); rx_disp3 ($3, 5); } 223 224/* ---------------------------------------------------------------------- */ 225 226 | BSR EXPR 227 { if (rx_intop ($2, 16, 16)) 228 { B1 (0x39); PC2 ($2); } 229 else if (rx_intop ($2, 24, 24)) 230 { B1 (0x05); PC3 ($2); } 231 else 232 { rx_relax (RX_RELAX_BRANCH, 0); 233 rx_linkrelax_branch (); 234 B1 (0x39); PC2 ($2); } } 235 | BSR DOT_A EXPR 236 { B1 (0x05), PC3 ($3); } 237 238/* ---------------------------------------------------------------------- */ 239 240 | BCND DOT_S EXPR 241 { if ($1 == COND_EQ || $1 == COND_NE) 242 { B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($3, 5); } 243 else 244 as_bad (_("Only BEQ and BNE may have .S")); } 245 246/* ---------------------------------------------------------------------- */ 247 248 | BCND DOT_B EXPR 249 { B1 (0x20); F ($1, 4, 4); PC1 ($3); } 250 251 | BRA DOT_B EXPR 252 { B1 (0x2e), PC1 ($3); } 253 254/* ---------------------------------------------------------------------- */ 255 256 | BRA DOT_W EXPR 257 { B1 (0x38), PC2 ($3); } 258 | BSR DOT_W EXPR 259 { B1 (0x39), PC2 ($3); } 260 | BCND DOT_W EXPR 261 { if ($1 == COND_EQ || $1 == COND_NE) 262 { B1 ($1 == COND_EQ ? 0x3a : 0x3b); PC2 ($3); } 263 else 264 as_bad (_("Only BEQ and BNE may have .W")); } 265 | BCND EXPR 266 { if ($1 == COND_EQ || $1 == COND_NE) 267 { 268 rx_relax (RX_RELAX_BRANCH, 0); 269 rx_linkrelax_branch (); 270 B1 ($1 == COND_EQ ? 0x10 : 0x18); rx_disp3 ($2, 5); 271 } 272 else 273 { 274 rx_relax (RX_RELAX_BRANCH, 0); 275 /* This is because we might turn it into a 276 jump-over-jump long branch. */ 277 rx_linkrelax_branch (); 278 B1 (0x20); F ($1, 4, 4); PC1 ($2); 279 } } 280 281/* ---------------------------------------------------------------------- */ 282 283 | MOV DOT_B '#' EXPR ',' '[' REG ']' 284 { B2 (0xf8, 0x04); F ($7, 8, 4); IMMB ($4, 12);} 285 286 | MOV DOT_W '#' EXPR ',' '[' REG ']' 287 { B2 (0xf8, 0x01); F ($7, 8, 4); IMMW ($4, 12);} 288 289 | MOV DOT_L '#' EXPR ',' '[' REG ']' 290 { B2 (0xf8, 0x02); F ($7, 8, 4); IMM ($4, 12);} 291 292 | MOV DOT_B '#' EXPR ',' disp '[' REG ']' 293 /* rx_disp5op changes the value if it succeeds, so keep it last. */ 294 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, BSIZE)) 295 { B2 (0x3c, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 296 else 297 { B2 (0xf8, 0x04); F ($8, 8, 4); DSP ($6, 6, BSIZE); O1 ($4); 298 if ($4.X_op != O_constant && $4.X_op != O_big) rx_linkrelax_imm (12); } } 299 300 | MOV DOT_W '#' EXPR ',' disp '[' REG ']' 301 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, WSIZE)) 302 { B2 (0x3d, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 303 else 304 { B2 (0xf8, 0x01); F ($8, 8, 4); DSP ($6, 6, WSIZE); IMMW ($4, 12); } } 305 306 | MOV DOT_L '#' EXPR ',' disp '[' REG ']' 307 { if ($8 <= 7 && rx_uintop ($4, 8) && rx_disp5op0 (&$6, LSIZE)) 308 { B2 (0x3e, 0); rx_field5s2 ($6); F ($8, 9, 3); O1 ($4); } 309 else 310 { B2 (0xf8, 0x02); F ($8, 8, 4); DSP ($6, 6, LSIZE); IMM ($4, 12); } } 311 312/* ---------------------------------------------------------------------- */ 313 314 | RTSD '#' EXPR ',' REG '-' REG 315 { B2 (0x3f, 0); F ($5, 8, 4); F ($7, 12, 4); rtsd_immediate ($3); 316 if ($5 == 0) 317 rx_error (_("RTSD cannot pop R0")); 318 if ($5 > $7) 319 rx_error (_("RTSD first reg must be <= second reg")); } 320 321/* ---------------------------------------------------------------------- */ 322 323 | CMP REG ',' REG 324 { B2 (0x47, 0); F ($2, 8, 4); F ($4, 12, 4); } 325 326/* ---------------------------------------------------------------------- */ 327 328 | CMP disp '[' REG ']' DOT_UB ',' REG 329 { B2 (0x44, 0); F ($4, 8, 4); F ($8, 12, 4); DSP ($2, 6, BSIZE); } 330 331 | CMP disp '[' REG ']' memex ',' REG 332 { B3 (MEMEX, 0x04, 0); F ($6, 8, 2); F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, sizemap[$6]); } 333 334/* ---------------------------------------------------------------------- */ 335 336 | MOVU bw REG ',' REG 337 { B2 (0x5b, 0x00); F ($2, 5, 1); F ($3, 8, 4); F ($5, 12, 4); } 338 339/* ---------------------------------------------------------------------- */ 340 341 | MOVU bw '[' REG ']' ',' REG 342 { B2 (0x58, 0x00); F ($2, 5, 1); F ($4, 8, 4); F ($7, 12, 4); } 343 344 | MOVU bw EXPR '[' REG ']' ',' REG 345 { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2)) 346 { B2 (0xb0, 0); F ($2, 4, 1); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); } 347 else 348 { B2 (0x58, 0x00); F ($2, 5, 1); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } } 349 350/* ---------------------------------------------------------------------- */ 351 352 | SUB '#' EXPR ',' REG 353 { if (rx_uintop ($3, 4)) 354 { B2 (0x60, 0); FE ($3, 8, 4); F ($5, 12, 4); } 355 else 356 /* This is really an add, but we negate the immediate. */ 357 { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); NIMM ($3, 6); } } 358 359 | CMP '#' EXPR ',' REG 360 { if (rx_uintop ($3, 4)) 361 { B2 (0x61, 0); FE ($3, 8, 4); F ($5, 12, 4); } 362 else if (rx_uintop ($3, 8)) 363 { B2 (0x75, 0x50); F ($5, 12, 4); UO1 ($3); } 364 else 365 { B2 (0x74, 0x00); F ($5, 12, 4); IMM ($3, 6); } } 366 367 | ADD '#' EXPR ',' REG 368 { if (rx_uintop ($3, 4)) 369 { B2 (0x62, 0); FE ($3, 8, 4); F ($5, 12, 4); } 370 else 371 { B2 (0x70, 0); F ($5, 8, 4); F ($5, 12, 4); IMM ($3, 6); } } 372 373 | MUL '#' EXPR ',' REG 374 { if (rx_uintop ($3, 4)) 375 { B2 (0x63, 0); FE ($3, 8, 4); F ($5, 12, 4); } 376 else 377 { B2 (0x74, 0x10); F ($5, 12, 4); IMM ($3, 6); } } 378 379 | AND_ '#' EXPR ',' REG 380 { if (rx_uintop ($3, 4)) 381 { B2 (0x64, 0); FE ($3, 8, 4); F ($5, 12, 4); } 382 else 383 { B2 (0x74, 0x20); F ($5, 12, 4); IMM ($3, 6); } } 384 385 | OR '#' EXPR ',' REG 386 { if (rx_uintop ($3, 4)) 387 { B2 (0x65, 0); FE ($3, 8, 4); F ($5, 12, 4); } 388 else 389 { B2 (0x74, 0x30); F ($5, 12, 4); IMM ($3, 6); } } 390 391 | MOV DOT_L '#' EXPR ',' REG 392 { if (rx_uintop ($4, 4)) 393 { B2 (0x66, 0); FE ($4, 8, 4); F ($6, 12, 4); } 394 else if (rx_uintop ($4, 8)) 395 { B2 (0x75, 0x40); F ($6, 12, 4); UO1 ($4); } 396 else 397 { B2 (0xfb, 0x02); F ($6, 8, 4); IMM ($4, 12); } } 398 399 | MOV '#' EXPR ',' REG 400 { if (rx_uintop ($3, 4)) 401 { B2 (0x66, 0); FE ($3, 8, 4); F ($5, 12, 4); } 402 else if (rx_uintop ($3, 8)) 403 { B2 (0x75, 0x40); F ($5, 12, 4); UO1 ($3); } 404 else 405 { B2 (0xfb, 0x02); F ($5, 8, 4); IMM ($3, 12); } } 406 407/* ---------------------------------------------------------------------- */ 408 409 | RTSD '#' EXPR 410 { B1 (0x67); rtsd_immediate ($3); } 411 412/* ---------------------------------------------------------------------- */ 413 414 | SHLR { sub_op = 0; } op_shift 415 | SHAR { sub_op = 1; } op_shift 416 | SHLL { sub_op = 2; } op_shift 417 418/* ---------------------------------------------------------------------- */ 419 420 | PUSHM REG '-' REG 421 { 422 if ($2 == $4) 423 { B2 (0x7e, 0x80); F (LSIZE, 10, 2); F ($2, 12, 4); } 424 else 425 { B2 (0x6e, 0); F ($2, 8, 4); F ($4, 12, 4); } 426 if ($2 == 0) 427 rx_error (_("PUSHM cannot push R0")); 428 if ($2 > $4) 429 rx_error (_("PUSHM first reg must be <= second reg")); } 430 431/* ---------------------------------------------------------------------- */ 432 433 | POPM REG '-' REG 434 { 435 if ($2 == $4) 436 { B2 (0x7e, 0xb0); F ($2, 12, 4); } 437 else 438 { B2 (0x6f, 0); F ($2, 8, 4); F ($4, 12, 4); } 439 if ($2 == 0) 440 rx_error (_("POPM cannot pop R0")); 441 if ($2 > $4) 442 rx_error (_("POPM first reg must be <= second reg")); } 443 444/* ---------------------------------------------------------------------- */ 445 446 | ADD '#' EXPR ',' REG ',' REG 447 { B2 (0x70, 0x00); F ($5, 8, 4); F ($7, 12, 4); IMM ($3, 6); } 448 449/* ---------------------------------------------------------------------- */ 450 451 | INT '#' EXPR 452 { B2(0x75, 0x60), UO1 ($3); } 453 454/* ---------------------------------------------------------------------- */ 455 456 | BSET '#' EXPR ',' REG 457 { B2 (0x78, 0); FE ($3, 7, 5); F ($5, 12, 4); } 458 | BCLR '#' EXPR ',' REG 459 { B2 (0x7a, 0); FE ($3, 7, 5); F ($5, 12, 4); } 460 461/* ---------------------------------------------------------------------- */ 462 463 | BTST '#' EXPR ',' REG 464 { B2 (0x7c, 0x00); FE ($3, 7, 5); F ($5, 12, 4); } 465 466/* ---------------------------------------------------------------------- */ 467 468 | SAT REG 469 { B2 (0x7e, 0x30); F ($2, 12, 4); } 470 | RORC REG 471 { B2 (0x7e, 0x40); F ($2, 12, 4); } 472 | ROLC REG 473 { B2 (0x7e, 0x50); F ($2, 12, 4); } 474 475/* ---------------------------------------------------------------------- */ 476 477 | PUSH bwl REG 478 { B2 (0x7e, 0x80); F ($2, 10, 2); F ($3, 12, 4); } 479 480/* ---------------------------------------------------------------------- */ 481 482 | POP REG 483 { B2 (0x7e, 0xb0); F ($2, 12, 4); } 484 485/* ---------------------------------------------------------------------- */ 486 487 | PUSHC CREG 488 { if ($2 == 13) 489 { rx_check_v2 (); } 490 if ($2 < 16) 491 { B2 (0x7e, 0xc0); F ($2, 12, 4); } 492 else 493 as_bad (_("PUSHC can only push the first 16 control registers")); } 494 495/* ---------------------------------------------------------------------- */ 496 497 | POPC CREG 498 { if ($2 == 13) 499 { rx_check_v2 (); } 500 if ($2 < 16) 501 { B2 (0x7e, 0xe0); F ($2, 12, 4); } 502 else 503 as_bad (_("POPC can only pop the first 16 control registers")); } 504 505/* ---------------------------------------------------------------------- */ 506 507 | SETPSW flag 508 { B2 (0x7f, 0xa0); F ($2, 12, 4); } 509 | CLRPSW flag 510 { B2 (0x7f, 0xb0); F ($2, 12, 4); } 511 512/* ---------------------------------------------------------------------- */ 513 514 | JMP REG 515 { B2 (0x7f, 0x00); F ($2, 12, 4); } 516 | JSR REG 517 { B2 (0x7f, 0x10); F ($2, 12, 4); } 518 | BRA opt_l REG 519 { B2 (0x7f, 0x40); F ($3, 12, 4); } 520 | BSR opt_l REG 521 { B2 (0x7f, 0x50); F ($3, 12, 4); } 522 523/* ---------------------------------------------------------------------- */ 524 525 | SCMPU 526 { B2 (0x7f, 0x83); rx_note_string_insn_use (); } 527 | SMOVU 528 { B2 (0x7f, 0x87); rx_note_string_insn_use (); } 529 | SMOVB 530 { B2 (0x7f, 0x8b); rx_note_string_insn_use (); } 531 | SMOVF 532 { B2 (0x7f, 0x8f); rx_note_string_insn_use (); } 533 534/* ---------------------------------------------------------------------- */ 535 536 | SUNTIL bwl 537 { B2 (0x7f, 0x80); F ($2, 14, 2); rx_note_string_insn_use (); } 538 | SWHILE bwl 539 { B2 (0x7f, 0x84); F ($2, 14, 2); rx_note_string_insn_use (); } 540 | SSTR bwl 541 { B2 (0x7f, 0x88); F ($2, 14, 2); } 542 543/* ---------------------------------------------------------------------- */ 544 545 | RMPA bwl 546 { B2 (0x7f, 0x8c); F ($2, 14, 2); rx_note_string_insn_use (); } 547 548/* ---------------------------------------------------------------------- */ 549 550 | RTFI 551 { B2 (0x7f, 0x94); } 552 | RTE 553 { B2 (0x7f, 0x95); } 554 | WAIT 555 { B2 (0x7f, 0x96); } 556 | SATR 557 { B2 (0x7f, 0x93); } 558 559/* ---------------------------------------------------------------------- */ 560 561 | MVTIPL '#' EXPR 562 { B3 (0x75, 0x70, 0x00); FE ($3, 20, 4); } 563 564/* ---------------------------------------------------------------------- */ 565 566 /* rx_disp5op changes the value if it succeeds, so keep it last. */ 567 | MOV bwl REG ',' EXPR '[' REG ']' 568 { if ($3 <= 7 && $7 <= 7 && rx_disp5op (&$5, $2)) 569 { B2 (0x80, 0); F ($2, 2, 2); F ($7, 9, 3); F ($3, 13, 3); rx_field5s ($5); } 570 else 571 { B2 (0xc3, 0x00); F ($2, 2, 2); F ($7, 8, 4); F ($3, 12, 4); DSP ($5, 4, $2); }} 572 573/* ---------------------------------------------------------------------- */ 574 575 | MOV bwl EXPR '[' REG ']' ',' REG 576 { if ($5 <= 7 && $8 <= 7 && rx_disp5op (&$3, $2)) 577 { B2 (0x88, 0); F ($2, 2, 2); F ($5, 9, 3); F ($8, 13, 3); rx_field5s ($3); } 578 else 579 { B2 (0xcc, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($8, 12, 4); DSP ($3, 6, $2); } } 580 581/* ---------------------------------------------------------------------- */ 582 583 /* MOV a,b - if a is a reg and b is mem, src and dest are 584 swapped. */ 585 586 /* We don't use "disp" here because it causes a shift/reduce 587 conflict with the other displacement-less patterns. */ 588 589 | MOV bwl REG ',' '[' REG ']' 590 { B2 (0xc3, 0x00); F ($2, 2, 2); F ($6, 8, 4); F ($3, 12, 4); } 591 592/* ---------------------------------------------------------------------- */ 593 594 | MOV bwl '[' REG ']' ',' disp '[' REG ']' 595 { B2 (0xc0, 0); F ($2, 2, 2); F ($4, 8, 4); F ($9, 12, 4); DSP ($7, 4, $2); } 596 597/* ---------------------------------------------------------------------- */ 598 599 | MOV bwl EXPR '[' REG ']' ',' disp '[' REG ']' 600 { B2 (0xc0, 0x00); F ($2, 2, 2); F ($5, 8, 4); F ($10, 12, 4); DSP ($3, 6, $2); DSP ($8, 4, $2); } 601 602/* ---------------------------------------------------------------------- */ 603 604 | MOV bwl REG ',' REG 605 { B2 (0xcf, 0x00); F ($2, 2, 2); F ($3, 8, 4); F ($5, 12, 4); } 606 607/* ---------------------------------------------------------------------- */ 608 609 | MOV bwl '[' REG ']' ',' REG 610 { B2 (0xcc, 0x00); F ($2, 2, 2); F ($4, 8, 4); F ($7, 12, 4); } 611 612/* ---------------------------------------------------------------------- */ 613 614 | BSET '#' EXPR ',' disp '[' REG ']' DOT_B 615 { B2 (0xf0, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 616 | BCLR '#' EXPR ',' disp '[' REG ']' DOT_B 617 { B2 (0xf0, 0x08); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 618 | BTST '#' EXPR ',' disp '[' REG ']' DOT_B 619 { B2 (0xf4, 0x00); F ($7, 8, 4); FE ($3, 13, 3); DSP ($5, 6, BSIZE); } 620 621/* ---------------------------------------------------------------------- */ 622 623 | PUSH bwl disp '[' REG ']' 624 { B2 (0xf4, 0x08); F ($2, 14, 2); F ($5, 8, 4); DSP ($3, 6, $2); } 625 626/* ---------------------------------------------------------------------- */ 627 628 | SBB { sub_op = 0; } op_dp20_rm_l 629 | NEG { sub_op = 1; sub_op2 = 1; } op_dp20_rr 630 | ADC { sub_op = 2; } op_dp20_rim_l 631 | ABS { sub_op = 3; sub_op2 = 2; } op_dp20_rr 632 | MAX { sub_op = 4; } op_dp20_rim 633 | MIN { sub_op = 5; } op_dp20_rim 634 | EMUL { sub_op = 6; } op_dp20_i 635 | EMULU { sub_op = 7; } op_dp20_i 636 | DIV { sub_op = 8; } op_dp20_rim 637 | DIVU { sub_op = 9; } op_dp20_rim 638 | TST { sub_op = 12; } op_dp20_rim 639 | XOR { sub_op = 13; } op_xor 640 | NOT { sub_op = 14; sub_op2 = 0; } op_dp20_rr 641 | STZ { sub_op = 14; sub_op2 = 0; } op_dp20_ri 642 | STNZ { sub_op = 15; sub_op2 = 1; } op_dp20_ri 643 644/* ---------------------------------------------------------------------- */ 645 646 | EMUL { sub_op = 6; } op_xchg 647 | EMULU { sub_op = 7; } op_xchg 648 | XCHG { sub_op = 16; } op_xchg 649 | ITOF { sub_op = 17; } op_xchg 650 | UTOF { sub_op = 21; } op_xchg 651 652/* ---------------------------------------------------------------------- */ 653 654 | BSET REG ',' REG 655 { id24 (1, 0x63, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 656 | BCLR REG ',' REG 657 { id24 (1, 0x67, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 658 | BTST REG ',' REG 659 { id24 (1, 0x6b, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 660 | BNOT REG ',' REG 661 { id24 (1, 0x6f, 0x00); F ($4, 16, 4); F ($2, 20, 4); } 662 663 | BSET REG ',' disp '[' REG ']' opt_b 664 { id24 (1, 0x60, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 665 | BCLR REG ',' disp '[' REG ']' opt_b 666 { id24 (1, 0x64, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 667 | BTST REG ',' disp '[' REG ']' opt_b 668 { id24 (1, 0x68, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 669 | BNOT REG ',' disp '[' REG ']' opt_b 670 { id24 (1, 0x6c, 0x00); F ($6, 16, 4); F ($2, 20, 4); DSP ($4, 14, BSIZE); } 671 672/* ---------------------------------------------------------------------- */ 673 674 | FSUB { sub_op = 0; } float3_op 675 | FCMP { sub_op = 1; } float2_op 676 | FADD { sub_op = 2; } float3_op 677 | FMUL { sub_op = 3; } float3_op 678 | FDIV { sub_op = 4; } float2_op 679 | FSQRT { sub_op = 8; } float2_op_ni 680 | FTOI { sub_op = 5; } float2_op_ni 681 | FTOU { sub_op = 9; } float2_op_ni 682 | ROUND { sub_op = 6; } float2_op_ni 683 684/* ---------------------------------------------------------------------- */ 685 686 687/* ---------------------------------------------------------------------- */ 688 689 | SCCND DOT_L REG 690 { id24 (1, 0xdb, 0x00); F ($1, 20, 4); F ($3, 16, 4); } 691 | SCCND bwl disp '[' REG ']' 692 { id24 (1, 0xd0, 0x00); F ($1, 20, 4); F ($2, 12, 2); F ($5, 16, 4); DSP ($3, 14, $2); } 693 694/* ---------------------------------------------------------------------- */ 695 696 | BMCND '#' EXPR ',' disp '[' REG ']' opt_b 697 { id24 (1, 0xe0, 0x00); F ($1, 20, 4); FE ($3, 11, 3); 698 F ($7, 16, 4); DSP ($5, 14, BSIZE); } 699 700/* ---------------------------------------------------------------------- */ 701 702 | BNOT '#' EXPR ',' disp '[' REG ']' opt_b 703 { id24 (1, 0xe0, 0x0f); FE ($3, 11, 3); F ($7, 16, 4); 704 DSP ($5, 14, BSIZE); } 705 706/* ---------------------------------------------------------------------- */ 707 708 | MULHI REG ',' REG 709 { id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 710 | MULHI REG ',' REG ',' ACC 711 { rx_check_v2 (); id24 (2, 0x00, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 712 | MULLO REG ',' REG 713 { id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 714 | MULLO REG ',' REG ',' ACC 715 { rx_check_v2 (); id24 (2, 0x01, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 716 | MACHI REG ',' REG 717 { id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 718 | MACHI REG ',' REG ',' ACC 719 { rx_check_v2 (); id24 (2, 0x04, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 720 | MACLO REG ',' REG 721 { id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); } 722 | MACLO REG ',' REG ',' ACC 723 { rx_check_v2 (); id24 (2, 0x05, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 724 725/* ---------------------------------------------------------------------- */ 726 727 /* We don't have syntax for these yet. */ 728 | MVTACHI REG 729 { id24 (2, 0x17, 0x00); F ($2, 20, 4); } 730 | MVTACHI REG ',' ACC 731 { rx_check_v2 (); id24 (2, 0x17, 0x00); F ($2, 20, 4); F ($4, 16, 1); } 732 | MVTACLO REG 733 { id24 (2, 0x17, 0x10); F ($2, 20, 4); } 734 | MVTACLO REG ',' ACC 735 { rx_check_v2 (); id24 (2, 0x17, 0x10); F ($2, 20, 4); F ($4, 16, 1); } 736 | MVFACHI REG 737 { id24 (2, 0x1f, 0x00); F ($2, 20, 4); } 738 | MVFACHI { sub_op = 0; } mvfa_op 739 | MVFACMI REG 740 { id24 (2, 0x1f, 0x20); F ($2, 20, 4); } 741 | MVFACMI { sub_op = 2; } mvfa_op 742 | MVFACLO REG 743 { id24 (2, 0x1f, 0x10); F ($2, 20, 4); } 744 | MVFACLO { sub_op = 1; } mvfa_op 745 | RACW '#' EXPR 746 { id24 (2, 0x18, 0x00); 747 if (rx_uintop ($3, 4) && exp_val($3) == 1) 748 ; 749 else if (rx_uintop ($3, 4) && exp_val($3) == 2) 750 F (1, 19, 1); 751 else 752 as_bad (_("RACW expects #1 or #2"));} 753 | RACW '#' EXPR ',' ACC 754 { rx_check_v2 (); id24 (2, 0x18, 0x00); F ($5, 16, 1); 755 if (rx_uintop ($3, 4) && exp_val($3) == 1) 756 ; 757 else if (rx_uintop ($3, 4) && exp_val($3) == 2) 758 F (1, 19, 1); 759 else 760 as_bad (_("RACW expects #1 or #2"));} 761 762/* ---------------------------------------------------------------------- */ 763 764 | MOV bwl REG ',' '[' REG '+' ']' 765 { id24 (2, 0x20, 0); F ($2, 14, 2); F ($6, 16, 4); F ($3, 20, 4); } 766 | MOV bwl REG ',' '[' '-' REG ']' 767 { id24 (2, 0x24, 0); F ($2, 14, 2); F ($7, 16, 4); F ($3, 20, 4); } 768 769/* ---------------------------------------------------------------------- */ 770 771 | MOV bwl '[' REG '+' ']' ',' REG 772 { id24 (2, 0x28, 0); F ($2, 14, 2); F ($4, 16, 4); F ($8, 20, 4); } 773 | MOV bwl '[' '-' REG ']' ',' REG 774 { id24 (2, 0x2c, 0); F ($2, 14, 2); F ($5, 16, 4); F ($8, 20, 4); } 775 776/* ---------------------------------------------------------------------- */ 777 778 | MOVU bw '[' REG '+' ']' ',' REG 779 { id24 (2, 0x38, 0); F ($2, 15, 1); F ($4, 16, 4); F ($8, 20, 4); } 780 | MOVU bw '[' '-' REG ']' ',' REG 781 { id24 (2, 0x3c, 0); F ($2, 15, 1); F ($5, 16, 4); F ($8, 20, 4); } 782 783/* ---------------------------------------------------------------------- */ 784 785 | ROTL { sub_op = 6; } op_shift_rot 786 | ROTR { sub_op = 4; } op_shift_rot 787 | REVW { sub_op = 5; } op_shift_rot 788 | REVL { sub_op = 7; } op_shift_rot 789 790/* ---------------------------------------------------------------------- */ 791 792 | MVTC REG ',' CREG 793 { if ($4 == 13) 794 rx_check_v2 (); 795 id24 (2, 0x68, 0x00); F ($4 % 16, 20, 4); F ($4 / 16, 15, 1); 796 F ($2, 16, 4); } 797 798/* ---------------------------------------------------------------------- */ 799 800 | MVFC CREG ',' REG 801 { if ($2 == 13) 802 rx_check_v2 (); 803 id24 (2, 0x6a, 0); F ($2, 15, 5); F ($4, 20, 4); } 804 805/* ---------------------------------------------------------------------- */ 806 807 | ROTL '#' EXPR ',' REG 808 { id24 (2, 0x6e, 0); FE ($3, 15, 5); F ($5, 20, 4); } 809 | ROTR '#' EXPR ',' REG 810 { id24 (2, 0x6c, 0); FE ($3, 15, 5); F ($5, 20, 4); } 811 812/* ---------------------------------------------------------------------- */ 813 814 | MVTC '#' EXPR ',' CREG 815 { if ($5 == 13) 816 rx_check_v2 (); 817 id24 (2, 0x73, 0x00); F ($5, 19, 5); IMM ($3, 12); } 818 819/* ---------------------------------------------------------------------- */ 820 821 | BMCND '#' EXPR ',' REG 822 { id24 (2, 0xe0, 0x00); F ($1, 16, 4); FE ($3, 11, 5); 823 F ($5, 20, 4); } 824 825/* ---------------------------------------------------------------------- */ 826 827 | BNOT '#' EXPR ',' REG 828 { id24 (2, 0xe0, 0xf0); FE ($3, 11, 5); F ($5, 20, 4); } 829 830/* ---------------------------------------------------------------------- */ 831 832 | MOV bwl REG ',' '[' REG ',' REG ']' 833 { id24 (3, 0x00, 0); F ($2, 10, 2); F ($6, 12, 4); F ($8, 16, 4); F ($3, 20, 4); } 834 835 | MOV bwl '[' REG ',' REG ']' ',' REG 836 { id24 (3, 0x40, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); } 837 838 | MOVU bw '[' REG ',' REG ']' ',' REG 839 { id24 (3, 0xc0, 0); F ($2, 10, 2); F ($4, 12, 4); F ($6, 16, 4); F ($9, 20, 4); } 840 841/* ---------------------------------------------------------------------- */ 842 843 | SUB { sub_op = 0; } op_subadd 844 | ADD { sub_op = 2; } op_subadd 845 | MUL { sub_op = 3; } op_subadd 846 | AND_ { sub_op = 4; } op_subadd 847 | OR { sub_op = 5; } op_subadd 848 849/* ---------------------------------------------------------------------- */ 850/* There is no SBB #imm so we fake it with ADC. */ 851 852 | SBB '#' EXPR ',' REG 853 { id24 (2, 0x70, 0x20); F ($5, 20, 4); NBIMM ($3, 12); } 854 855/* ---------------------------------------------------------------------- */ 856 857 | MOVCO REG ',' '[' REG ']' 858 { rx_check_v2 (); B3 (0xfd, 0x27, 0x00); F ($5, 16, 4); F ($2, 20, 4); } 859 860/* ---------------------------------------------------------------------- */ 861 862 | MOVLI '[' REG ']' ',' REG 863 { rx_check_v2 (); B3 (0xfd, 0x2f, 0x00); F ($3, 16, 4); F ($6, 20, 4); } 864 865/* ---------------------------------------------------------------------- */ 866 867 | EMACA REG ',' REG ',' ACC 868 { rx_check_v2 (); id24 (2, 0x07, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 869 | EMSBA REG ',' REG ',' ACC 870 { rx_check_v2 (); id24 (2, 0x47, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 871 | EMULA REG ',' REG ',' ACC 872 { rx_check_v2 (); id24 (2, 0x03, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 873 | MACLH REG ',' REG ',' ACC 874 { rx_check_v2 (); id24 (2, 0x06, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 875 | MSBHI REG ',' REG ',' ACC 876 { rx_check_v2 (); id24 (2, 0x44, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 877 | MSBLH REG ',' REG ',' ACC 878 { rx_check_v2 (); id24 (2, 0x46, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 879 | MSBLO REG ',' REG ',' ACC 880 { rx_check_v2 (); id24 (2, 0x45, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 881 | MULLH REG ',' REG ',' ACC 882 { rx_check_v2 (); id24 (2, 0x02, 0x00); F ($2, 16, 4); F ($4, 20, 4); F ($6, 12, 1); } 883 | MVFACGU { sub_op = 3; } mvfa_op 884 | MVTACGU REG ',' ACC 885 { rx_check_v2 (); id24 (2, 0x17, 0x30); F ($4, 16, 1); F ($2, 20, 4); } 886 | RACL '#' EXPR ',' ACC 887 { rx_check_v2 (); id24 (2, 0x19, 0x00); F ($5, 16, 1); 888 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 889 ; 890 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 891 F (1, 19, 1); 892 else 893 as_bad (_("RACL expects #1 or #2"));} 894 | RDACL '#' EXPR ',' ACC 895 { rx_check_v2 (); id24 (2, 0x19, 0x40); F ($5, 16, 1); 896 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 897 ; 898 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 899 F (1, 19, 1); 900 else 901 as_bad (_("RDACL expects #1 or #2"));} 902 | RDACW '#' EXPR ',' ACC 903 { rx_check_v2 (); id24 (2, 0x18, 0x40); F ($5, 16, 1); 904 if (rx_uintop ($3, 4) && $3.X_add_number == 1) 905 ; 906 else if (rx_uintop ($3, 4) && $3.X_add_number == 2) 907 F (1, 19, 1); 908 else 909 as_bad (_("RDACW expects #1 or #2"));} 910 911/* ---------------------------------------------------------------------- */ 912 | BFMOV { rx_check_v3(); sub_op = 1; } op_bfield 913 | BFMOVZ { rx_check_v3(); sub_op = 0; } op_bfield 914 915/* ---------------------------------------------------------------------- */ 916 | RSTR { rx_check_v3(); sub_op = 1; } op_save_rstr 917 | SAVE { rx_check_v3(); sub_op = 0; } op_save_rstr 918 919/* ---------------------------------------------------------------------- */ 920 | DABS { rx_check_dfpu(); sub_op = 0x0c; sub_op2 = 0x01; } double2_op 921 | DNEG { rx_check_dfpu(); sub_op = 0x0c; sub_op2 = 0x02; } double2_op 922 | DROUND { rx_check_dfpu(); sub_op = 0x0d; sub_op2 = 0x0d; } double2_op 923 | DSQRT { rx_check_dfpu(); sub_op = 0x0d; sub_op2 = 0x00; } double2_op 924 | DTOF { rx_check_dfpu(); sub_op = 0x0d; sub_op2 = 0x0c; } double2_op 925 | DTOI { rx_check_dfpu(); sub_op = 0x0d; sub_op2 = 0x08;} double2_op 926 | DTOU { rx_check_dfpu(); sub_op = 0x0d; sub_op2 = 0x09; } double2_op 927 | DADD { rx_check_dfpu(); sub_op = 0x00; } double3_op 928 | DDIV { rx_check_dfpu(); sub_op = 0x05; } double3_op 929 | DMUL { rx_check_dfpu(); sub_op = 0x02; } double3_op 930 | DSUB { rx_check_dfpu(); sub_op = 0x01; } double3_op 931 | DCMP DREG ',' DREG { rx_check_dfpu(); 932 B4(0x76, 0x90, 0x08, 0x00); F($1, 24, 4); F($2, 28, 4); F($4, 16, 4); } 933 | DMOV DOT_D REG ',' DREGH 934 { rx_check_dfpu(); 935 B4(0xfd, 0x77, 0x80, 0x03); F($3, 20, 4); F($5, 24, 4); } 936 | DMOV DOT_L REG ',' DREGH 937 { rx_check_dfpu(); 938 B4(0xfd, 0x77, 0x80, 0x02); F($3, 20, 4); F($5, 24, 4); } 939 | DMOV DOT_L REG ',' DREGL 940 { rx_check_dfpu(); 941 B4(0xfd, 0x77, 0x80, 0x00); F($3, 20, 4); F($5, 24, 4); } 942 | DMOV DOT_L DREGH ',' REG 943 { rx_check_dfpu(); 944 B4(0xfd, 0x75, 0x80, 0x02); F($3, 24, 4); F($5, 20, 4); } 945 | DMOV DOT_L DREGL ',' REG 946 { rx_check_dfpu(); 947 B4(0xfd, 0x75, 0x80, 0x00); F($3, 24, 4); F($5, 20, 4); } 948 | DMOV DOT_D DREG ',' DREG 949 { rx_check_dfpu(); 950 B4(0x76, 0x90, 0x0c, 0x00); F($3, 16, 4); F($5, 24, 4); } 951 | DMOV DOT_D DREG ',' '[' REG ']' 952 { rx_check_dfpu(); 953 B4(0xfc, 0x78, 0x08, 0x00); F($6, 16, 4); F($3, 24, 4); } 954 | DMOV DOT_D DREG ',' disp '[' REG ']' 955 { rx_check_dfpu(); 956 B3(0xfc, 0x78, 0x08); F($7, 16, 4); DSP($5, 14, DSIZE); 957 POST($3 << 4); } 958 | DMOV DOT_D '[' REG ']' ',' DREG 959 { rx_check_dfpu(); 960 B4(0xfc, 0xc8, 0x08, 0x00); F($4, 16, 4); F($7, 24, 4); } 961 | DMOV DOT_D disp '[' REG ']' ',' DREG 962 { rx_check_dfpu(); 963 B3(0xfc, 0xc8, 0x08); F($5, 16, 4); DSP($3, 14, DSIZE); 964 POST($8 << 4); } 965 | DMOV DOT_D '#' EXPR ',' DREGH 966 { rx_check_dfpu(); 967 B3(0xf9, 0x03, 0x03); F($6, 16, 4); IMM($4, -1); } 968 | DMOV DOT_L '#' EXPR ',' DREGH 969 { rx_check_dfpu(); 970 B3(0xf9, 0x03, 0x02); F($6, 16, 4); IMM($4, -1); } 971 | DMOV DOT_L '#' EXPR ',' DREGL 972 { rx_check_dfpu(); 973 B3(0xf9, 0x03, 0x00); F($6, 16, 4); IMM($4, -1); } 974 | DPOPM DOT_D DREG '-' DREG 975 { rx_check_dfpu(); 976 B3(0x75, 0xb8, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } 977 | DPOPM DOT_L DCREG '-' DCREG 978 { rx_check_dfpu(); 979 B3(0x75, 0xa8, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } 980 | DPUSHM DOT_D DREG '-' DREG 981 { rx_check_dfpu(); 982 B3(0x75, 0xb0, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } 983 | DPUSHM DOT_L DCREG '-' DCREG 984 { rx_check_dfpu(); 985 B3(0x75, 0xa0, 0x00); F($3, 16, 4); F($5 - $3, 20, 4); } 986 | MVFDC DCREG ',' REG 987 { rx_check_dfpu(); 988 B4(0xfd, 0x75, 0x80, 0x04); F($2, 24, 4); F($4, 20, 4); } 989 | MVFDR 990 { rx_check_dfpu(); B3(0x75, 0x90, 0x1b); } 991 | MVTDC REG ',' DCREG 992 { rx_check_dfpu(); 993 B4(0xfd, 0x77, 0x80, 0x04); F($2, 24, 4); F($4, 20, 4); } 994 | FTOD REG ',' DREG 995 { rx_check_dfpu(); 996 B4(0xfd, 0x77, 0x80, 0x0a); F($2, 24, 4); F($4, 20, 4); } 997 | ITOD REG ',' DREG 998 { rx_check_dfpu(); 999 B4(0xfd, 0x77, 0x80, 0x09); F($2, 24, 4); F($4, 20, 4); } 1000 | UTOD REG ',' DREG 1001 { rx_check_dfpu(); 1002 B4(0xfd, 0x77, 0x80, 0x0d); F($2, 24, 4); F($4, 20, 4); } 1003 1004/* ---------------------------------------------------------------------- */ 1005 1006 ; 1007 1008/* ====================================================================== */ 1009 1010op_subadd 1011 : REG ',' REG 1012 { B2 (0x43 + (sub_op<<2), 0); F ($1, 8, 4); F ($3, 12, 4); } 1013 | disp '[' REG ']' DOT_UB ',' REG 1014 { B2 (0x40 + (sub_op<<2), 0); F ($3, 8, 4); F ($7, 12, 4); DSP ($1, 6, BSIZE); } 1015 | disp '[' REG ']' memex ',' REG 1016 { B3 (MEMEX, sub_op<<2, 0); F ($5, 8, 2); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, sizemap[$5]); } 1017 | REG ',' REG ',' REG 1018 { id24 (4, sub_op<<4, 0), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); } 1019 ; 1020 1021/* sbb, neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */ 1022 1023op_dp20_rm_l 1024 : REG ',' REG 1025 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 1026 | disp '[' REG ']' opt_l ',' REG 1027 { B4 (MEMEX, 0xa0, 0x00 + sub_op, 0x00); 1028 F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, LSIZE); } 1029 ; 1030 1031/* neg, adc, abs, max, min, div, divu, tst, not, xor, stz, stnz, emul, emulu */ 1032 1033op_dp20_rm 1034 : REG ',' REG 1035 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 1036 | disp '[' REG ']' DOT_UB ',' REG 1037 { id24 (1, 0x00 + (sub_op<<2), 0x00); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); } 1038 | disp '[' REG ']' memex ',' REG 1039 { B4 (MEMEX, 0x20 + ($5 << 6), 0x00 + sub_op, 0x00); 1040 F ($3, 24, 4); F ($7, 28, 4); DSP ($1, 14, sizemap[$5]); } 1041 ; 1042 1043op_dp20_i 1044 : '#' EXPR ',' REG 1045 { id24 (2, 0x70, sub_op<<4); F ($4, 20, 4); IMM ($2, 12); } 1046 ; 1047 1048op_dp20_rim 1049 : op_dp20_rm 1050 | op_dp20_i 1051 ; 1052 1053op_dp20_rim_l 1054 : op_dp20_rm_l 1055 | op_dp20_i 1056 ; 1057 1058op_dp20_rr 1059 : REG ',' REG 1060 { id24 (1, 0x03 + (sub_op<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 1061 | REG 1062 { B2 (0x7e, sub_op2 << 4); F ($1, 12, 4); } 1063 ; 1064 1065op_dp20_r 1066 : REG ',' REG 1067 { id24 (1, 0x4b + (sub_op2<<2), 0x00); F ($1, 16, 4); F ($3, 20, 4); } 1068 ; 1069 1070op_dp20_ri 1071 : { rx_check_v2 (); } 1072 op_dp20_r 1073 | op_dp20_i 1074 ; 1075 1076/* xchg, utof, itof, emul, emulu */ 1077op_xchg 1078 : REG ',' REG 1079 { id24 (1, 0x03 + (sub_op<<2), 0); F ($1, 16, 4); F ($3, 20, 4); } 1080 | disp '[' REG ']' DOT_UB ',' REG 1081 { id24 (1, 0x00 + (sub_op<<2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, BSIZE); } 1082 | disp '[' REG ']' memex ',' REG 1083 { B4 (MEMEX, 0x20, 0x00 + sub_op, 0); F ($5, 8, 2); F ($3, 24, 4); F ($7, 28, 4); 1084 DSP ($1, 14, sizemap[$5]); } 1085 ; 1086 1087/* 000:SHLR, 001:SHAR, 010:SHLL, 011:-, 100:ROTR, 101:REVW, 110:ROTL, 111:REVL */ 1088op_shift_rot 1089 : REG ',' REG 1090 { id24 (2, 0x60 + sub_op, 0); F ($1, 16, 4); F ($3, 20, 4); } 1091 ; 1092op_shift 1093 : '#' EXPR ',' REG 1094 { B2 (0x68 + (sub_op<<1), 0); FE ($2, 7, 5); F ($4, 12, 4); } 1095 | '#' EXPR ',' REG ',' REG 1096 { id24 (2, 0x80 + (sub_op << 5), 0); FE ($2, 11, 5); F ($4, 16, 4); F ($6, 20, 4); } 1097 | op_shift_rot 1098 ; 1099 1100float3_op 1101 : '#' EXPR ',' REG 1102 { rx_check_float_support (); id24 (2, 0x72, sub_op << 4); F ($4, 20, 4); O4 ($2); } 1103 | REG ',' REG 1104 { rx_check_float_support (); id24 (1, 0x83 + (sub_op << 2), 0); F ($1, 16, 4); F ($3, 20, 4); } 1105 | disp '[' REG ']' opt_l ',' REG 1106 { rx_check_float_support (); id24 (1, 0x80 + (sub_op << 2), 0); F ($3, 16, 4); F ($7, 20, 4); DSP ($1, 14, LSIZE); } 1107 | REG ',' REG ',' REG 1108 { rx_check_v2 (); id24 (4, 0x80 + (sub_op << 4), 0 ); F ($1, 16, 4); F ($3, 20, 4); F ($5, 12, 4); } 1109 ; 1110 1111float2_op 1112 : { rx_check_float_support (); } 1113 '#' EXPR ',' REG 1114 { id24 (2, 0x72, sub_op << 4); F ($5, 20, 4); O4 ($3); } 1115 | float2_op_ni 1116 ; 1117 1118float2_op_ni 1119 : { rx_check_float_support (); } 1120 REG ',' REG 1121 { id24 (1, 0x83 + (sub_op << 2), 0); F ($2, 16, 4); F ($4, 20, 4); } 1122 | { rx_check_float_support (); } 1123 disp '[' REG ']' opt_l ',' REG 1124 { id24 (1, 0x80 + (sub_op << 2), 0); F ($4, 16, 4); F ($8, 20, 4); DSP ($2, 14, LSIZE); } 1125 ; 1126 1127mvfa_op 1128 : { rx_check_v2 (); } 1129 '#' EXPR ',' ACC ',' REG 1130 { id24 (2, 0x1e, sub_op << 4); F ($7, 20, 4); F ($5, 16, 1); 1131 if (rx_uintop ($3, 4)) 1132 { 1133 switch (exp_val ($3)) 1134 { 1135 case 0: 1136 F (1, 15, 1); 1137 break; 1138 case 1: 1139 F (1, 15, 1); 1140 F (1, 17, 1); 1141 break; 1142 case 2: 1143 break; 1144 default: 1145 as_bad (_("IMM expects #0 to #2"));} 1146 } else 1147 as_bad (_("IMM expects #0 to #2"));} 1148 ; 1149 1150op_xor 1151 : op_dp20_rim 1152 | REG ',' REG ',' REG 1153 { rx_check_v3(); B3(0xff,0x60,0x00), F ($5, 12, 4), F ($1, 16, 4), F ($3, 20, 4); } 1154 ; 1155 1156op_bfield 1157 : { rx_check_v3(); } 1158 '#' EXPR ',' '#' EXPR ',' '#' EXPR ',' REG ',' REG 1159 { rx_range($3, 0, 31); rx_range($6, 0, 31); rx_range($9, 1, 31); 1160 B3(0xfc, 0x5a + (sub_op << 2), 0); F($11, 16, 4); F($13, 20, 4); 1161 rx_bfield($3, $6, $9);} 1162 ; 1163 1164op_save_rstr 1165 : '#' EXPR 1166 { B3(0xfd,0x76,0xe0 + (sub_op << 4)); UO1($2); } 1167 | REG 1168 { B4(0xfd,0x76,0xc0 + (sub_op << 4), 0x00); F($1, 20, 4); } 1169 ; 1170 1171double2_op 1172 : DREG ',' DREG 1173 { B4(0x76, 0x90, sub_op, sub_op2); F($1, 16, 4); F($3, 24, 4);} 1174 1175double3_op 1176 : DREG ',' DREG ',' DREG 1177 { B4(0x76, 0x90, sub_op, 0x00); F($1, 28, 4); F($3, 16,4); F($5, 24, 4);} 1178 1179/* ====================================================================== */ 1180 1181disp : { $$ = zero_expr (); } 1182 | EXPR { $$ = $1; } 1183 ; 1184 1185flag : { need_flag = 1; } FLAG { need_flag = 0; $$ = $2; } 1186 ; 1187 1188/* DOT_UB is not listed here, it's handled with a separate pattern. */ 1189/* Use sizemap[$n] to get LSIZE etc. */ 1190memex : DOT_B { $$ = 0; } 1191 | DOT_W { $$ = 1; } 1192 | { $$ = 2; } 1193 | DOT_L { $$ = 2; } 1194 | DOT_UW { $$ = 3; } 1195 ; 1196 1197bwl : { $$ = LSIZE; } 1198 | DOT_B { $$ = BSIZE; } 1199 | DOT_W { $$ = WSIZE; } 1200 | DOT_L { $$ = LSIZE; } 1201 ; 1202 1203bw : { $$ = 1; } 1204 | DOT_B { $$ = 0; } 1205 | DOT_W { $$ = 1; } 1206 ; 1207 1208opt_l : {} 1209 | DOT_L {} 1210 ; 1211 1212opt_b : {} 1213 | DOT_B {} 1214 ; 1215 1216%% 1217/* ====================================================================== */ 1218 1219static struct 1220{ 1221 const char * string; 1222 int token; 1223 int val; 1224} 1225token_table[] = 1226{ 1227 { "r0", REG, 0 }, 1228 { "r1", REG, 1 }, 1229 { "r2", REG, 2 }, 1230 { "r3", REG, 3 }, 1231 { "r4", REG, 4 }, 1232 { "r5", REG, 5 }, 1233 { "r6", REG, 6 }, 1234 { "r7", REG, 7 }, 1235 { "r8", REG, 8 }, 1236 { "r9", REG, 9 }, 1237 { "r10", REG, 10 }, 1238 { "r11", REG, 11 }, 1239 { "r12", REG, 12 }, 1240 { "r13", REG, 13 }, 1241 { "r14", REG, 14 }, 1242 { "r15", REG, 15 }, 1243 1244 { "psw", CREG, 0 }, 1245 { "pc", CREG, 1 }, 1246 { "usp", CREG, 2 }, 1247 { "fpsw", CREG, 3 }, 1248 /* reserved */ 1249 /* reserved */ 1250 /* reserved */ 1251 { "wr", CREG, 7 }, 1252 1253 { "bpsw", CREG, 8 }, 1254 { "bpc", CREG, 9 }, 1255 { "isp", CREG, 10 }, 1256 { "fintv", CREG, 11 }, 1257 { "intb", CREG, 12 }, 1258 { "extb", CREG, 13 }, 1259 1260 { "pbp", CREG, 16 }, 1261 { "pben", CREG, 17 }, 1262 1263 { "bbpsw", CREG, 24 }, 1264 { "bbpc", CREG, 25 }, 1265 1266 { "dr0", DREG, 0 }, 1267 { "dr1", DREG, 1 }, 1268 { "dr2", DREG, 2 }, 1269 { "dr3", DREG, 3 }, 1270 { "dr4", DREG, 4 }, 1271 { "dr5", DREG, 5 }, 1272 { "dr6", DREG, 6 }, 1273 { "dr7", DREG, 7 }, 1274 { "dr8", DREG, 8 }, 1275 { "dr9", DREG, 9 }, 1276 { "dr10", DREG, 10 }, 1277 { "dr11", DREG, 11 }, 1278 { "dr12", DREG, 12 }, 1279 { "dr13", DREG, 13 }, 1280 { "dr14", DREG, 14 }, 1281 { "dr15", DREG, 15 }, 1282 1283 { "drh0", DREGH, 0 }, 1284 { "drh1", DREGH, 1 }, 1285 { "drh2", DREGH, 2 }, 1286 { "drh3", DREGH, 3 }, 1287 { "drh4", DREGH, 4 }, 1288 { "drh5", DREGH, 5 }, 1289 { "drh6", DREGH, 6 }, 1290 { "drh7", DREGH, 7 }, 1291 { "drh8", DREGH, 8 }, 1292 { "drh9", DREGH, 9 }, 1293 { "drh10", DREGH, 10 }, 1294 { "drh11", DREGH, 11 }, 1295 { "drh12", DREGH, 12 }, 1296 { "drh13", DREGH, 13 }, 1297 { "drh14", DREGH, 14 }, 1298 { "drh15", DREGH, 15 }, 1299 1300 { "drl0", DREGL, 0 }, 1301 { "drl1", DREGL, 1 }, 1302 { "drl2", DREGL, 2 }, 1303 { "drl3", DREGL, 3 }, 1304 { "drl4", DREGL, 4 }, 1305 { "drl5", DREGL, 5 }, 1306 { "drl6", DREGL, 6 }, 1307 { "drl7", DREGL, 7 }, 1308 { "drl8", DREGL, 8 }, 1309 { "drl9", DREGL, 9 }, 1310 { "drl10", DREGL, 10 }, 1311 { "drl11", DREGL, 11 }, 1312 { "drl12", DREGL, 12 }, 1313 { "drl13", DREGL, 13 }, 1314 { "drl14", DREGL, 14 }, 1315 { "drl15", DREGL, 15 }, 1316 1317 { "DPSW", DCREG, 0 }, 1318 { "DCMR", DCREG, 1 }, 1319 { "DCENT", DCREG, 2 }, 1320 { "DEPC", DCREG, 3 }, 1321 { "DCR0", DCREG, 0 }, 1322 { "DCR1", DCREG, 1 }, 1323 { "DCR2", DCREG, 2 }, 1324 { "DCR3", DCREG, 3 }, 1325 1326 { ".s", DOT_S, 0 }, 1327 { ".b", DOT_B, 0 }, 1328 { ".w", DOT_W, 0 }, 1329 { ".l", DOT_L, 0 }, 1330 { ".a", DOT_A , 0}, 1331 { ".ub", DOT_UB, 0 }, 1332 { ".uw", DOT_UW , 0}, 1333 { ".d", DOT_D , 0}, 1334 1335 { "c", FLAG, 0 }, 1336 { "z", FLAG, 1 }, 1337 { "s", FLAG, 2 }, 1338 { "o", FLAG, 3 }, 1339 { "i", FLAG, 8 }, 1340 { "u", FLAG, 9 }, 1341 1342 { "a0", ACC, 0 }, 1343 { "a1", ACC, 1 }, 1344 1345#define OPC(x) { #x, x, IS_OPCODE } 1346 OPC(ABS), 1347 OPC(ADC), 1348 OPC(ADD), 1349 { "and", AND_, IS_OPCODE }, 1350 OPC(BCLR), 1351 OPC(BCND), 1352 OPC(BFMOV), 1353 OPC(BFMOVZ), 1354 OPC(BMCND), 1355 OPC(BNOT), 1356 OPC(BRA), 1357 OPC(BRK), 1358 OPC(BSET), 1359 OPC(BSR), 1360 OPC(BTST), 1361 OPC(CLRPSW), 1362 OPC(CMP), 1363 OPC(DABS), 1364 OPC(DADD), 1365 OPC(DBT), 1366 OPC(DDIV), 1367 OPC(DIV), 1368 OPC(DIVU), 1369 OPC(DMOV), 1370 OPC(DMUL), 1371 OPC(DNEG), 1372 OPC(DPOPM), 1373 OPC(DPUSHM), 1374 OPC(DROUND), 1375 OPC(DSQRT), 1376 OPC(DSUB), 1377 OPC(DTOF), 1378 OPC(DTOI), 1379 OPC(DTOU), 1380 OPC(EDIV), 1381 OPC(EDIVU), 1382 OPC(EMACA), 1383 OPC(EMSBA), 1384 OPC(EMUL), 1385 OPC(EMULA), 1386 OPC(EMULU), 1387 OPC(FADD), 1388 OPC(FCMP), 1389 OPC(FDIV), 1390 OPC(FMUL), 1391 OPC(FREIT), 1392 OPC(FSQRT), 1393 OPC(FTOD), 1394 OPC(FTOU), 1395 OPC(FSUB), 1396 OPC(FTOI), 1397 OPC(INT), 1398 OPC(ITOD), 1399 OPC(ITOF), 1400 OPC(JMP), 1401 OPC(JSR), 1402 OPC(MVFACGU), 1403 OPC(MVFACHI), 1404 OPC(MVFACMI), 1405 OPC(MVFACLO), 1406 OPC(MVFC), 1407 OPC(MVFDC), 1408 OPC(MVFDR), 1409 OPC(MVTDC), 1410 OPC(MVTACGU), 1411 OPC(MVTACHI), 1412 OPC(MVTACLO), 1413 OPC(MVTC), 1414 OPC(MVTIPL), 1415 OPC(MACHI), 1416 OPC(MACLO), 1417 OPC(MACLH), 1418 OPC(MAX), 1419 OPC(MIN), 1420 OPC(MOV), 1421 OPC(MOVCO), 1422 OPC(MOVLI), 1423 OPC(MOVU), 1424 OPC(MSBHI), 1425 OPC(MSBLH), 1426 OPC(MSBLO), 1427 OPC(MUL), 1428 OPC(MULHI), 1429 OPC(MULLH), 1430 OPC(MULLO), 1431 OPC(MULU), 1432 OPC(NEG), 1433 OPC(NOP), 1434 OPC(NOT), 1435 OPC(OR), 1436 OPC(POP), 1437 OPC(POPC), 1438 OPC(POPM), 1439 OPC(PUSH), 1440 OPC(PUSHA), 1441 OPC(PUSHC), 1442 OPC(PUSHM), 1443 OPC(RACL), 1444 OPC(RACW), 1445 OPC(RDACL), 1446 OPC(RDACW), 1447 OPC(REIT), 1448 OPC(REVL), 1449 OPC(REVW), 1450 OPC(RMPA), 1451 OPC(ROLC), 1452 OPC(RORC), 1453 OPC(ROTL), 1454 OPC(ROTR), 1455 OPC(ROUND), 1456 OPC(RSTR), 1457 OPC(RTE), 1458 OPC(RTFI), 1459 OPC(RTS), 1460 OPC(RTSD), 1461 OPC(SAT), 1462 OPC(SATR), 1463 OPC(SAVE), 1464 OPC(SBB), 1465 OPC(SCCND), 1466 OPC(SCMPU), 1467 OPC(SETPSW), 1468 OPC(SHAR), 1469 OPC(SHLL), 1470 OPC(SHLR), 1471 OPC(SMOVB), 1472 OPC(SMOVF), 1473 OPC(SMOVU), 1474 OPC(SSTR), 1475 OPC(STNZ), 1476 OPC(STOP), 1477 OPC(STZ), 1478 OPC(SUB), 1479 OPC(SUNTIL), 1480 OPC(SWHILE), 1481 OPC(TST), 1482 OPC(UTOD), 1483 OPC(UTOF), 1484 OPC(WAIT), 1485 OPC(XCHG), 1486 OPC(XOR), 1487}; 1488 1489#define NUM_TOKENS (sizeof (token_table) / sizeof (token_table[0])) 1490 1491static struct 1492{ 1493 const char * string; 1494 int token; 1495} 1496condition_opcode_table[] = 1497{ 1498 { "b", BCND }, 1499 { "bm", BMCND }, 1500 { "sc", SCCND }, 1501}; 1502 1503#define NUM_CONDITION_OPCODES (sizeof (condition_opcode_table) / sizeof (condition_opcode_table[0])) 1504 1505struct condition_symbol 1506{ 1507 const char * string; 1508 int val; 1509}; 1510 1511static struct condition_symbol condition_table[] = 1512{ 1513 { "z", 0 }, 1514 { "eq", 0 }, 1515 { "geu", 2 }, 1516 { "c", 2 }, 1517 { "gtu", 4 }, 1518 { "pz", 6 }, 1519 { "ge", 8 }, 1520 { "gt", 10 }, 1521 { "o", 12}, 1522 /* always = 14 */ 1523 { "nz", 1 }, 1524 { "ne", 1 }, 1525 { "ltu", 3 }, 1526 { "nc", 3 }, 1527 { "leu", 5 }, 1528 { "n", 7 }, 1529 { "lt", 9 }, 1530 { "le", 11 }, 1531 { "no", 13 }, 1532 /* never = 15 */ 1533}; 1534 1535static struct condition_symbol double_condition_table[] = 1536{ 1537 { "un", 1 }, 1538 { "eq", 2 }, 1539 { "lt", 4 }, 1540 { "le", 6 }, 1541}; 1542 1543#define NUM_CONDITIONS (sizeof (condition_table) / sizeof (condition_table[0])) 1544#define NUM_DOUBLE_CONDITIONS (sizeof (double_condition_table) / sizeof (double_condition_table[0])) 1545 1546void 1547rx_lex_init (char * beginning, char * ending) 1548{ 1549 rx_init_start = beginning; 1550 rx_lex_start = beginning; 1551 rx_lex_end = ending; 1552 rx_in_brackets = 0; 1553 rx_last_token = 0; 1554 1555 setbuf (stdout, 0); 1556} 1557 1558static int 1559check_condition (const char * base, struct condition_symbol *t, unsigned int num) 1560{ 1561 char * cp; 1562 unsigned int i; 1563 1564 if ((unsigned) (rx_lex_end - rx_lex_start) < strlen (base) + 1) 1565 return 0; 1566 if (memcmp (rx_lex_start, base, strlen (base))) 1567 return 0; 1568 cp = rx_lex_start + strlen (base); 1569 for (i = 0; i < num; i ++) 1570 { 1571 if (strcasecmp (cp, t[i].string) == 0) 1572 { 1573 rx_lval.regno = t[i].val; 1574 return 1; 1575 } 1576 } 1577 return 0; 1578} 1579 1580static int 1581rx_lex (void) 1582{ 1583 unsigned int ci; 1584 char * save_input_pointer; 1585 1586 while (ISSPACE (*rx_lex_start) 1587 && rx_lex_start != rx_lex_end) 1588 rx_lex_start ++; 1589 1590 rx_last_exp_start = rx_lex_start; 1591 1592 if (rx_lex_start == rx_lex_end) 1593 return 0; 1594 1595 if (ISALPHA (*rx_lex_start) 1596 || (rx_pid_register != -1 && memcmp (rx_lex_start, "%pidreg", 7) == 0) 1597 || (rx_gp_register != -1 && memcmp (rx_lex_start, "%gpreg", 6) == 0) 1598 || (*rx_lex_start == '.' && ISALPHA (rx_lex_start[1]))) 1599 { 1600 unsigned int i; 1601 char * e; 1602 char save; 1603 1604 for (e = rx_lex_start + 1; 1605 e < rx_lex_end && ISALNUM (*e); 1606 e ++) 1607 ; 1608 save = *e; 1609 *e = 0; 1610 1611 if (strcmp (rx_lex_start, "%pidreg") == 0) 1612 { 1613 { 1614 rx_lval.regno = rx_pid_register; 1615 *e = save; 1616 rx_lex_start = e; 1617 rx_last_token = REG; 1618 return REG; 1619 } 1620 } 1621 1622 if (strcmp (rx_lex_start, "%gpreg") == 0) 1623 { 1624 { 1625 rx_lval.regno = rx_gp_register; 1626 *e = save; 1627 rx_lex_start = e; 1628 rx_last_token = REG; 1629 return REG; 1630 } 1631 } 1632 1633 if (rx_last_token == 0) 1634 { 1635 for (ci = 0; ci < NUM_CONDITION_OPCODES; ci ++) 1636 if (check_condition (condition_opcode_table[ci].string, 1637 condition_table, NUM_CONDITIONS)) 1638 { 1639 *e = save; 1640 rx_lex_start = e; 1641 rx_last_token = condition_opcode_table[ci].token; 1642 return condition_opcode_table[ci].token; 1643 } 1644 if (check_condition ("dcmp", double_condition_table, 1645 NUM_DOUBLE_CONDITIONS)) 1646 { 1647 *e = save; 1648 rx_lex_start = e; 1649 rx_last_token = DCMP; 1650 return DCMP; 1651 } 1652 } 1653 1654 for (i = 0; i < NUM_TOKENS; i++) 1655 if (strcasecmp (rx_lex_start, token_table[i].string) == 0 1656 && !(token_table[i].val == IS_OPCODE && rx_last_token != 0) 1657 && !(token_table[i].token == FLAG && !need_flag)) 1658 { 1659 rx_lval.regno = token_table[i].val; 1660 *e = save; 1661 rx_lex_start = e; 1662 rx_last_token = token_table[i].token; 1663 return token_table[i].token; 1664 } 1665 *e = save; 1666 } 1667 1668 if (rx_last_token == 0) 1669 { 1670 rx_last_token = UNKNOWN_OPCODE; 1671 return UNKNOWN_OPCODE; 1672 } 1673 1674 if (rx_last_token == UNKNOWN_OPCODE) 1675 return 0; 1676 1677 if (*rx_lex_start == '[') 1678 rx_in_brackets = 1; 1679 if (*rx_lex_start == ']') 1680 rx_in_brackets = 0; 1681 1682 if (rx_in_brackets 1683 || rx_last_token == REG || rx_last_token == DREG || rx_last_token == DCREG 1684 || strchr ("[],#", *rx_lex_start)) 1685 { 1686 rx_last_token = *rx_lex_start; 1687 return *rx_lex_start ++; 1688 } 1689 1690 save_input_pointer = input_line_pointer; 1691 input_line_pointer = rx_lex_start; 1692 rx_lval.exp.X_md = 0; 1693 expression (&rx_lval.exp); 1694 1695 /* We parse but ignore any :<size> modifier on expressions. */ 1696 if (*input_line_pointer == ':') 1697 { 1698 char *cp; 1699 1700 for (cp = input_line_pointer + 1; *cp && cp < rx_lex_end; cp++) 1701 if (!ISDIGIT (*cp)) 1702 break; 1703 if (cp > input_line_pointer+1) 1704 input_line_pointer = cp; 1705 } 1706 1707 rx_lex_start = input_line_pointer; 1708 input_line_pointer = save_input_pointer; 1709 rx_last_token = EXPR; 1710 return EXPR; 1711} 1712 1713int 1714rx_error (const char * str) 1715{ 1716 int len; 1717 1718 len = rx_last_exp_start - rx_init_start; 1719 1720 as_bad ("%s", rx_init_start); 1721 as_bad ("%*s^ %s", len, "", str); 1722 return 0; 1723} 1724 1725static int 1726rx_intop (expressionS exp, int nbits, int opbits) 1727{ 1728 long v; 1729 long mask, msb; 1730 1731 if (exp.X_op == O_big) 1732 { 1733 if (nbits == 32) 1734 return 1; 1735 if (exp.X_add_number == -1) 1736 return 0; 1737 } 1738 else if (exp.X_op != O_constant) 1739 return 0; 1740 v = exp.X_add_number; 1741 1742 msb = 1UL << (opbits - 1); 1743 mask = (1UL << opbits) - 1; 1744 1745 if ((v & msb) && ! (v & ~mask)) 1746 v -= 1UL << opbits; 1747 1748 switch (nbits) 1749 { 1750 case 4: 1751 return -0x8 <= v && v <= 0x7; 1752 case 5: 1753 return -0x10 <= v && v <= 0x17; 1754 case 8: 1755 return -0x80 <= v && v <= 0x7f; 1756 case 16: 1757 return -0x8000 <= v && v <= 0x7fff; 1758 case 24: 1759 return -0x800000 <= v && v <= 0x7fffff; 1760 case 32: 1761 return 1; 1762 default: 1763 printf ("rx_intop passed %d\n", nbits); 1764 abort (); 1765 } 1766 return 1; 1767} 1768 1769static int 1770rx_uintop (expressionS exp, int nbits) 1771{ 1772 unsigned long v; 1773 1774 if (exp.X_op != O_constant) 1775 return 0; 1776 v = exp.X_add_number; 1777 1778 switch (nbits) 1779 { 1780 case 4: 1781 return v <= 0xf; 1782 case 8: 1783 return v <= 0xff; 1784 case 16: 1785 return v <= 0xffff; 1786 case 24: 1787 return v <= 0xffffff; 1788 default: 1789 printf ("rx_uintop passed %d\n", nbits); 1790 abort (); 1791 } 1792 return 1; 1793} 1794 1795static int 1796rx_disp3op (expressionS exp) 1797{ 1798 unsigned long v; 1799 1800 if (exp.X_op != O_constant) 1801 return 0; 1802 v = exp.X_add_number; 1803 if (v < 3 || v > 10) 1804 return 0; 1805 return 1; 1806} 1807 1808static int 1809rx_disp5op (expressionS * exp, int msize) 1810{ 1811 long v; 1812 1813 if (exp->X_op != O_constant) 1814 return 0; 1815 v = exp->X_add_number; 1816 1817 switch (msize) 1818 { 1819 case BSIZE: 1820 if (0 <= v && v <= 31) 1821 return 1; 1822 break; 1823 case WSIZE: 1824 if (v & 1) 1825 return 0; 1826 if (0 <= v && v <= 63) 1827 { 1828 exp->X_add_number >>= 1; 1829 return 1; 1830 } 1831 break; 1832 case LSIZE: 1833 if (v & 3) 1834 return 0; 1835 if (0 <= v && v <= 127) 1836 { 1837 exp->X_add_number >>= 2; 1838 return 1; 1839 } 1840 break; 1841 } 1842 return 0; 1843} 1844 1845/* Just like the above, but allows a zero displacement. */ 1846 1847static int 1848rx_disp5op0 (expressionS * exp, int msize) 1849{ 1850 if (exp->X_op != O_constant) 1851 return 0; 1852 if (exp->X_add_number == 0) 1853 return 1; 1854 return rx_disp5op (exp, msize); 1855} 1856 1857static int 1858exp_val (expressionS exp) 1859{ 1860 if (exp.X_op != O_constant) 1861 { 1862 rx_error (_("constant expected")); 1863 return 0; 1864 } 1865 return exp.X_add_number; 1866} 1867 1868static expressionS 1869zero_expr (void) 1870{ 1871 /* Static, so program load sets it to all zeros, which is what we want. */ 1872 static expressionS zero; 1873 zero.X_op = O_constant; 1874 return zero; 1875} 1876 1877static int 1878immediate (expressionS exp, int type, int pos, int bits) 1879{ 1880 /* We will emit constants ourselves here, so negate them. */ 1881 if (type == RXREL_NEGATIVE && exp.X_op == O_constant) 1882 exp.X_add_number = - exp.X_add_number; 1883 if (type == RXREL_NEGATIVE_BORROW) 1884 { 1885 if (exp.X_op == O_constant) 1886 exp.X_add_number = - exp.X_add_number - 1; 1887 else 1888 rx_error (_("sbb cannot use symbolic immediates")); 1889 } 1890 1891 if (pos >= 0 && rx_intop (exp, 8, bits)) 1892 { 1893 rx_op (exp, 1, type); 1894 return 1; 1895 } 1896 else if (pos >= 0 && rx_intop (exp, 16, bits)) 1897 { 1898 rx_op (exp, 2, type); 1899 return 2; 1900 } 1901 else if (pos >= 0 && rx_uintop (exp, 16) && bits == 16) 1902 { 1903 rx_op (exp, 2, type); 1904 return 2; 1905 } 1906 else if (pos >= 0 && rx_intop (exp, 24, bits)) 1907 { 1908 rx_op (exp, 3, type); 1909 return 3; 1910 } 1911 else if (pos < 0 || rx_intop (exp, 32, bits)) 1912 { 1913 rx_op (exp, 4, type); 1914 return 0; 1915 } 1916 else if (type == RXREL_SIGNED && pos >= 0) 1917 { 1918 /* This is a symbolic immediate, we will relax it later. */ 1919 rx_relax (RX_RELAX_IMM, pos); 1920 rx_op (exp, linkrelax ? 4 : 1, type); 1921 return 1; 1922 } 1923 else 1924 { 1925 /* Let the linker deal with it. */ 1926 rx_op (exp, 4, type); 1927 return 0; 1928 } 1929} 1930 1931static int 1932displacement (expressionS exp, int msize) 1933{ 1934 int val; 1935 int vshift = 0; 1936 1937 if (exp.X_op == O_symbol 1938 && exp.X_md) 1939 { 1940 switch (exp.X_md) 1941 { 1942 case BFD_RELOC_GPREL16: 1943 switch (msize) 1944 { 1945 case BSIZE: 1946 exp.X_md = BFD_RELOC_RX_GPRELB; 1947 break; 1948 case WSIZE: 1949 exp.X_md = BFD_RELOC_RX_GPRELW; 1950 break; 1951 case LSIZE: 1952 exp.X_md = BFD_RELOC_RX_GPRELL; 1953 break; 1954 } 1955 O2 (exp); 1956 return 2; 1957 } 1958 } 1959 1960 if (exp.X_op == O_subtract) 1961 { 1962 exp.X_md = BFD_RELOC_RX_DIFF; 1963 O2 (exp); 1964 return 2; 1965 } 1966 1967 if (exp.X_op != O_constant) 1968 { 1969 rx_error (_("displacements must be constants")); 1970 return -1; 1971 } 1972 val = exp.X_add_number; 1973 1974 if (val == 0) 1975 return 0; 1976 1977 switch (msize) 1978 { 1979 case BSIZE: 1980 break; 1981 case WSIZE: 1982 if (val & 1) 1983 rx_error (_("word displacement not word-aligned")); 1984 vshift = 1; 1985 break; 1986 case LSIZE: 1987 if (val & 3) 1988 rx_error (_("long displacement not long-aligned")); 1989 vshift = 2; 1990 break; 1991 case DSIZE: 1992 if (val & 7) 1993 rx_error (_("double displacement not double-aligned")); 1994 vshift = 3; 1995 break; 1996 default: 1997 as_bad (_("displacement with unknown size (internal bug?)\n")); 1998 break; 1999 } 2000 2001 val >>= vshift; 2002 exp.X_add_number = val; 2003 2004 if (0 <= val && val <= 255 ) 2005 { 2006 O1 (exp); 2007 return 1; 2008 } 2009 2010 if (0 <= val && val <= 65535) 2011 { 2012 O2 (exp); 2013 return 2; 2014 } 2015 if (val < 0) 2016 rx_error (_("negative displacements not allowed")); 2017 else 2018 rx_error (_("displacement too large")); 2019 return -1; 2020} 2021 2022static void 2023rtsd_immediate (expressionS exp) 2024{ 2025 int val; 2026 2027 if (exp.X_op != O_constant) 2028 { 2029 rx_error (_("rtsd size must be constant")); 2030 return; 2031 } 2032 val = exp.X_add_number; 2033 if (val & 3) 2034 rx_error (_("rtsd size must be multiple of 4")); 2035 2036 if (val < 0 || val > 1020) 2037 rx_error (_("rtsd size must be 0..1020")); 2038 2039 val >>= 2; 2040 exp.X_add_number = val; 2041 O1 (exp); 2042} 2043 2044static void 2045rx_range (expressionS exp, int minv, int maxv) 2046{ 2047 int val; 2048 2049 if (exp.X_op != O_constant) 2050 return; 2051 2052 val = exp.X_add_number; 2053 if (val < minv || val > maxv) 2054 as_warn (_("Value %d out of range %d..%d"), val, minv, maxv); 2055} 2056 2057static void 2058rx_check_float_support (void) 2059{ 2060 if (rx_cpu == RX100 || rx_cpu == RX200) 2061 rx_error (_("target CPU type does not support floating point instructions")); 2062} 2063 2064static void 2065rx_check_v2 (void) 2066{ 2067 if (rx_cpu < RXV2) 2068 rx_error (_("target CPU type does not support v2 instructions")); 2069} 2070 2071static void 2072rx_check_v3 (void) 2073{ 2074 if (rx_cpu < RXV3) 2075 rx_error (_("target CPU type does not support v3 instructions")); 2076} 2077 2078static void 2079rx_check_dfpu (void) 2080{ 2081 if (rx_cpu != RXV3FPU) 2082 rx_error (_("target CPU type does not support double float instructions")); 2083} 2084