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