1bb16d227Schristos/* r8c.opc --- semantics for r8c opcodes. -*- mode: c -*- 2bb16d227Schristos 3*8b657b07SchristosCopyright (C) 2005-2023 Free Software Foundation, Inc. 4bb16d227SchristosContributed by Red Hat, Inc. 5bb16d227Schristos 6bb16d227SchristosThis file is part of the GNU simulators. 7bb16d227Schristos 8bb16d227SchristosThis program is free software; you can redistribute it and/or modify 9bb16d227Schristosit under the terms of the GNU General Public License as published by 10bb16d227Schristosthe Free Software Foundation; either version 3 of the License, or 11bb16d227Schristos(at your option) any later version. 12bb16d227Schristos 13bb16d227SchristosThis program is distributed in the hope that it will be useful, 14bb16d227Schristosbut WITHOUT ANY WARRANTY; without even the implied warranty of 15bb16d227SchristosMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16bb16d227SchristosGNU General Public License for more details. 17bb16d227Schristos 18bb16d227SchristosYou should have received a copy of the GNU General Public License 19bb16d227Schristosalong with this program. If not, see <http://www.gnu.org/licenses/>. */ 20bb16d227Schristos 21*8b657b07Schristos/* This must come before any other includes. */ 22*8b657b07Schristos#include "defs.h" 23bb16d227Schristos 24bb16d227Schristos#include <stdio.h> 25bb16d227Schristos#include <stdlib.h> 26bb16d227Schristos 27*8b657b07Schristos#include "ansidecl.h" 28bb16d227Schristos#include "cpu.h" 29bb16d227Schristos#include "mem.h" 30bb16d227Schristos#include "misc.h" 31bb16d227Schristos#include "int.h" 32bb16d227Schristos 33bb16d227Schristos#define tprintf if (trace) printf 34bb16d227Schristos 35bb16d227Schristosstatic unsigned char 36bb16d227Schristosgetbyte (void) 37bb16d227Schristos{ 38bb16d227Schristos int tsave = trace; 39bb16d227Schristos unsigned char b; 40bb16d227Schristos 41bb16d227Schristos if (trace == 1) 42bb16d227Schristos trace = 0; 43bb16d227Schristos b = mem_get_pc (); 44bb16d227Schristos regs.r_pc ++; 45bb16d227Schristos trace = tsave; 46bb16d227Schristos return b; 47bb16d227Schristos} 48bb16d227Schristos 49bb16d227Schristos#define M16C_ONLY() /* FIXME: add something here */ 50bb16d227Schristos 51bb16d227Schristos#define GETBYTE() (op[opi++] = getbyte()) 52bb16d227Schristos 53bb16d227Schristos#define UNSUPPORTED() unsupported("unsupported", orig_pc) 54bb16d227Schristos#define NOTYET() unsupported("unimplemented", orig_pc) 55bb16d227Schristos 56bb16d227Schristosstatic void 57bb16d227Schristosunsupported (char *tag, int orig_pc) 58bb16d227Schristos{ 59bb16d227Schristos int i; 60bb16d227Schristos printf("%s opcode at %08x\n", tag, orig_pc); 61bb16d227Schristos regs.r_pc = orig_pc; 62bb16d227Schristos for (i=0; i<2; i++) 63bb16d227Schristos { 64bb16d227Schristos int b = mem_get_pc(); 65bb16d227Schristos printf(" %s", bits(b>>4, 4)); 66bb16d227Schristos printf(" %s", bits(b, 4)); 67bb16d227Schristos regs.r_pc ++; 68bb16d227Schristos } 69bb16d227Schristos printf("\n"); 70bb16d227Schristos regs.r_pc = orig_pc; 71bb16d227Schristos for (i=0; i<6; i++) 72bb16d227Schristos { 73bb16d227Schristos printf(" %02x", mem_get_pc ()); 74bb16d227Schristos regs.r_pc ++; 75bb16d227Schristos } 76bb16d227Schristos printf("\n"); 77bb16d227Schristos exit(1); 78bb16d227Schristos} 79bb16d227Schristos 80bb16d227Schristosstatic int 81bb16d227SchristosIMM (int bw) 82bb16d227Schristos{ 83bb16d227Schristos int rv = getbyte (); 84bb16d227Schristos if (bw) 85bb16d227Schristos rv = rv + 256 * getbyte(); 86bb16d227Schristos if (bw == 2) 87bb16d227Schristos rv = rv + 65536 * getbyte(); 88bb16d227Schristos return rv; 89bb16d227Schristos} 90bb16d227Schristos 91bb16d227Schristos#define IMM4() (immm >= 8 ? 7 - immm : immm + 1) 92bb16d227Schristos 93bb16d227Schristos#define UNARY_SOP \ 94bb16d227Schristos dc = decode_srcdest4 (dest, w); \ 95bb16d227Schristos v = sign_ext (get_src (dc), w?16:8); 96bb16d227Schristos 97bb16d227Schristos#define UNARY_UOP \ 98bb16d227Schristos dc = decode_srcdest4 (dest, w); \ 99bb16d227Schristos v = get_src (dc); 100bb16d227Schristos 101bb16d227Schristos#define BINARY_SOP \ 102bb16d227Schristos sc = decode_srcdest4 (srcx, w); \ 103bb16d227Schristos dc = decode_srcdest4 (dest, w); \ 104bb16d227Schristos a = sign_ext (get_src (sc), w?16:8); \ 105bb16d227Schristos b = sign_ext (get_src (dc), w?16:8); 106bb16d227Schristos 107bb16d227Schristos#define BINARY_UOP \ 108bb16d227Schristos sc = decode_srcdest4 (srcx, w); \ 109bb16d227Schristos dc = decode_srcdest4 (dest, w); \ 110bb16d227Schristos a = get_src (sc); \ 111bb16d227Schristos b = get_src (dc); 112bb16d227Schristos 113bb16d227Schristos#define carry (FLAG_C ? 1 : 0) 114bb16d227Schristos 115bb16d227Schristosstatic void 116bb16d227Schristoscmp (int d, int s, int w) 117bb16d227Schristos{ 118bb16d227Schristos int a, b, f=0; 119bb16d227Schristos int mask = w ? 0xffff : 0xff; 120bb16d227Schristos a = d - s; 121bb16d227Schristos b = sign_ext (d, w?16:8) - sign_ext (s, w?16:8); 122bb16d227Schristos tprintf ("cmp: %x - %x = %08x, %x - %x = %d\n", 123bb16d227Schristos d, s, a, 124bb16d227Schristos sign_ext(d,w?16:8), sign_ext(s,w?16:8), b); 125bb16d227Schristos 126bb16d227Schristos if (b == 0) 127bb16d227Schristos f |= FLAGBIT_Z; 128bb16d227Schristos if (b & (w ? 0x8000 : 0x80)) 129bb16d227Schristos f |= FLAGBIT_S; 130bb16d227Schristos if ((d & mask) >= (s & mask)) 131bb16d227Schristos f |= FLAGBIT_C; 132bb16d227Schristos if (b < (w ? -32768 : -128) || b > (w ? 32767 : 127)) 133bb16d227Schristos f |= FLAGBIT_O; 134bb16d227Schristos 135bb16d227Schristos set_flags (FLAGBIT_Z | FLAGBIT_S | FLAGBIT_O | FLAGBIT_C, f); 136bb16d227Schristos} 137bb16d227Schristos 138bb16d227Schristosstatic void 139bb16d227Schristosdiv_op (int s, int u, int x, int w) 140bb16d227Schristos{ 141bb16d227Schristos srcdest sc; 142bb16d227Schristos int v, a, b; 143bb16d227Schristos 144bb16d227Schristos if (s == -1) 145bb16d227Schristos s = IMM(w); 146bb16d227Schristos else 147bb16d227Schristos { 148bb16d227Schristos sc = decode_srcdest4 (s, w); 149bb16d227Schristos s = get_src (sc); 150bb16d227Schristos } 151bb16d227Schristos 152bb16d227Schristos v = get_reg (w ? r2r0 : r0); 153bb16d227Schristos 154bb16d227Schristos if (!u) 155bb16d227Schristos { 156bb16d227Schristos s = sign_ext (s, w ? 16 : 8); 157bb16d227Schristos v = sign_ext (v, w ? 16 : 8); 158bb16d227Schristos } 159bb16d227Schristos 160bb16d227Schristos if (s == 0) 161bb16d227Schristos { 162bb16d227Schristos set_flags (FLAGBIT_O, FLAGBIT_O); 163bb16d227Schristos return; 164bb16d227Schristos } 165bb16d227Schristos 166bb16d227Schristos if (u) 167bb16d227Schristos { 168bb16d227Schristos a = (unsigned int)v / (unsigned int)s; 169bb16d227Schristos b = (unsigned int)v % (unsigned int)s; 170bb16d227Schristos } 171bb16d227Schristos else 172bb16d227Schristos { 173bb16d227Schristos a = v / s; 174bb16d227Schristos b = v % s; 175bb16d227Schristos } 176bb16d227Schristos if (x) 177bb16d227Schristos { 178bb16d227Schristos if ((s > 0 && b < 0) 179bb16d227Schristos || (s < 0 && b > 0)) 180bb16d227Schristos { 181bb16d227Schristos a --; 182bb16d227Schristos b += s; 183bb16d227Schristos } 184bb16d227Schristos } 185bb16d227Schristos tprintf ("%d / %d = %d rem %d\n", v, s, a, b); 186bb16d227Schristos if ((!u && (a > (w ? 32767 : 127) 187bb16d227Schristos || a < (w ? -32768 : -129))) 188bb16d227Schristos || (u && (a > (w ? 65536 : 255)))) 189bb16d227Schristos set_flags (FLAGBIT_O, FLAGBIT_O); 190bb16d227Schristos else 191bb16d227Schristos set_flags (FLAGBIT_O, 0); 192bb16d227Schristos 193bb16d227Schristos put_reg (w ? r0 : r0l, a); 194bb16d227Schristos put_reg (w ? r2 : r0h, b); 195bb16d227Schristos} 196bb16d227Schristos 197bb16d227Schristosstatic void 198bb16d227Schristosrot_op (srcdest sd, int rotc, int count) 199bb16d227Schristos{ 200bb16d227Schristos int mask = (sd.bytes == 2) ? 0xffff : 0xff; 201bb16d227Schristos int msb = (sd.bytes == 2) ? 0x8000 : 0x80; 202bb16d227Schristos int v = get_src (sd); 203bb16d227Schristos int c = carry, ct; 204bb16d227Schristos 205bb16d227Schristos tprintf("%s %x by %d\n", rotc ? "rotc" : "rot", v, count); 206bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 207bb16d227Schristos while (count > 0) 208bb16d227Schristos { 209bb16d227Schristos ct = (v & msb) ? 1 : 0; 210bb16d227Schristos v <<= 1; 211bb16d227Schristos v |= rotc ? c : ct; 212bb16d227Schristos v &= mask; 213bb16d227Schristos c = ct; 214bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 215bb16d227Schristos count --; 216bb16d227Schristos } 217bb16d227Schristos while (count < 0) 218bb16d227Schristos { 219bb16d227Schristos ct = v & 1; 220bb16d227Schristos v >>= 1; 221bb16d227Schristos v |= (rotc ? c : ct) * msb; 222bb16d227Schristos c = ct; 223bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 224bb16d227Schristos count ++; 225bb16d227Schristos } 226bb16d227Schristos put_dest (sd, v); 227bb16d227Schristos set_szc (v, sd.bytes, c); 228bb16d227Schristos} 229bb16d227Schristos 230bb16d227Schristosstatic void 231bb16d227Schristosshift_op (srcdest sd, int arith, int count) 232bb16d227Schristos{ 233bb16d227Schristos int mask = (sd.bytes == 2) ? 0xffff : 0xff; 234bb16d227Schristos int msb = (sd.bytes == 2) ? 0x8000 : 0x80; 235bb16d227Schristos int v = get_src (sd); 236bb16d227Schristos int c = 0; 237bb16d227Schristos 238bb16d227Schristos if (sd.bytes == 4) 239bb16d227Schristos { 240bb16d227Schristos mask = 0xffffffffU; 241bb16d227Schristos msb = 0x80000000U; 242bb16d227Schristos if (count > 16 || count < -16) 243bb16d227Schristos { 244bb16d227Schristos fprintf(stderr, "Error: SI shift of %d undefined\n", count); 245bb16d227Schristos exit(1); 246bb16d227Schristos } 247bb16d227Schristos if (count > 16) 248bb16d227Schristos count = (count - 1) % 16 + 1; 249bb16d227Schristos if (count < -16) 250bb16d227Schristos count = -((-count - 1) % 16 + 1); 251bb16d227Schristos } 252bb16d227Schristos 253bb16d227Schristos tprintf("%s %x by %d\n", arith ? "sha" : "shl", v, count); 254bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 255bb16d227Schristos while (count > 0) 256bb16d227Schristos { 257bb16d227Schristos c = (v & msb) ? 1 : 0; 258bb16d227Schristos v <<= 1; 259bb16d227Schristos v &= mask; 260bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 261bb16d227Schristos count --; 262bb16d227Schristos } 263bb16d227Schristos while (count < 0) 264bb16d227Schristos { 265bb16d227Schristos c = v & 1; 266bb16d227Schristos if (arith) 267bb16d227Schristos v = (v & msb) | (v >> 1); 268bb16d227Schristos else 269bb16d227Schristos v = (v >> 1) & (msb - 1); 270bb16d227Schristos tprintf (": %s %d\n", bits(v, 8*sd.bytes), c); 271bb16d227Schristos count ++; 272bb16d227Schristos } 273bb16d227Schristos put_dest (sd, v); 274bb16d227Schristos set_szc (v, sd.bytes, c); 275bb16d227Schristos} 276bb16d227Schristos 277bb16d227Schristos#define MATH_OP(dc,s,c,op,carryrel) \ 278bb16d227Schristos a = get_src(dc); \ 279bb16d227Schristos b = s & b2mask[dc.bytes]; \ 280bb16d227Schristos v2 = a op b op c; \ 281bb16d227Schristos tprintf("0x%x " #op " 0x%x " #op " 0x%x = 0x%x\n", a, b, c, v2); \ 282bb16d227Schristos a = sign_ext (a, dc.bytes * 8); \ 283bb16d227Schristos b = sign_ext (s, dc.bytes * 8); \ 284bb16d227Schristos v = a op b op c; \ 285bb16d227Schristos tprintf("%d " #op " %d " #op " %d = %d\n", a, b, c, v); \ 286bb16d227Schristos set_oszc (v, dc.bytes, v2 carryrel); \ 287bb16d227Schristos put_dest (dc, v2); 288bb16d227Schristos 289bb16d227Schristos#define BIT_OP(field,expr) \ 290bb16d227Schristos dc = decode_bit (field); \ 291bb16d227Schristos b = get_bit (dc); \ 292bb16d227Schristos v = expr; \ 293bb16d227Schristos tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \ 294bb16d227Schristos put_bit (dc, v); 295bb16d227Schristos 296bb16d227Schristos#define BIT_OPC(field,expr) \ 297bb16d227Schristos dc = decode_bit (field); \ 298bb16d227Schristos b = get_bit (dc); \ 299bb16d227Schristos v = expr; \ 300bb16d227Schristos tprintf ("b=%d, carry=%d, %s = %d\n", b, carry, #expr, v); \ 301bb16d227Schristos set_c (v); 302bb16d227Schristos 303bb16d227Schristos/* The "BMcnd dest" opcode uses a different encoding for the */ 304bb16d227Schristos/* condition than other opcodes. */ 305bb16d227Schristosstatic int bmcnd_cond_map[] = { 306bb16d227Schristos 0, 1, 2, 3, 8, 9, 10, 11, 4, 5, 6, 7, 12, 13, 14, 15 307bb16d227Schristos}; 308bb16d227Schristos 309bb16d227Schristosint 310bb16d227Schristosdecode_r8c (void) 311bb16d227Schristos{ 312bb16d227Schristos unsigned char op[40]; 313bb16d227Schristos int opi = 0; 314bb16d227Schristos int v, v2, a, b; 315bb16d227Schristos int orig_pc = get_reg (pc); 316bb16d227Schristos srcdest sc, dc; 317bb16d227Schristos int imm; 318bb16d227Schristos 319bb16d227Schristos step_result = M32C_MAKE_STEPPED (); 320bb16d227Schristos 321bb16d227Schristos tprintf("trace: decode pc = %05x\n", orig_pc); 322bb16d227Schristos 323bb16d227Schristos /** VARY dst 011 100 101 110 111 */ 324bb16d227Schristos 325bb16d227Schristos /** 0111 011w 1111 dest ABS.size dest */ 326bb16d227Schristos 327bb16d227Schristos UNARY_SOP; 328bb16d227Schristos a = v<0 ? -v : v; 329bb16d227Schristos tprintf("abs(%d) = %d\n", v, a); 330bb16d227Schristos set_osz(a, w+1); 331bb16d227Schristos put_dest (dc, a); 332bb16d227Schristos 333bb16d227Schristos /** 0111 011w 0110 dest ADC.size #IMM,dest */ 334bb16d227Schristos 335bb16d227Schristos dc = decode_srcdest4(dest, w); 336bb16d227Schristos imm = IMM(w); 337bb16d227Schristos MATH_OP (dc, imm, carry, +, > (w?0xffff:0xff)); 338bb16d227Schristos 339bb16d227Schristos /** 1011 000w srcx dest ADC.size src,dest */ 340bb16d227Schristos 341bb16d227Schristos sc = decode_srcdest4(srcx, w); 342bb16d227Schristos dc = decode_srcdest4(dest, w); 343bb16d227Schristos b = get_src (sc); 344bb16d227Schristos MATH_OP (dc, b, carry, +, > (w?0xffff:0xff)); 345bb16d227Schristos 346bb16d227Schristos /** 0111 011w 1110 dest ADCF.size dest */ 347bb16d227Schristos 348bb16d227Schristos dc = decode_srcdest4(dest, w); 349bb16d227Schristos MATH_OP (dc, 0, carry, +, > (w?0xffff:0xff)); 350bb16d227Schristos 351bb16d227Schristos /** 0111 011w 0100 dest ADD.size:G #imm,dest */ 352bb16d227Schristos 353bb16d227Schristos dc = decode_srcdest4(dest, w); 354bb16d227Schristos imm = IMM(w); 355bb16d227Schristos MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff)); 356bb16d227Schristos 357bb16d227Schristos /** 1100 100w immm dest ADD.size:Q #IMM,dest */ 358bb16d227Schristos 359bb16d227Schristos dc = decode_srcdest4(dest, w); 360bb16d227Schristos imm = sign_ext (immm, 4); 361bb16d227Schristos MATH_OP (dc, imm, 0, +, > (w?0xffff:0xff)); 362bb16d227Schristos 363bb16d227Schristos /** 1000 0dst ADD.B:S #IMM8,dst */ 364bb16d227Schristos 365bb16d227Schristos imm = IMM(0); 366bb16d227Schristos dc = decode_dest3 (dst, 0); 367bb16d227Schristos MATH_OP (dc, imm, 0, +, > 0xff); 368bb16d227Schristos 369bb16d227Schristos /** 1010 000w srcx dest ADD.size:G src,dest */ 370bb16d227Schristos 371bb16d227Schristos sc = decode_srcdest4(srcx, w); 372bb16d227Schristos dc = decode_srcdest4(dest, w); 373bb16d227Schristos b = get_src (sc); 374bb16d227Schristos MATH_OP (dc, b, 0, +, > (w?0xffff:0xff)); 375bb16d227Schristos 376bb16d227Schristos /** 0010 0d sr ADD.B:S src,R0L/R0H */ 377bb16d227Schristos 378bb16d227Schristos sc = decode_src2 (sr, 0, d); 379bb16d227Schristos dc = decode_dest1 (d, 0); 380bb16d227Schristos b = get_src (sc); 381bb16d227Schristos MATH_OP (dc, b, 0, +, > 0xff); 382bb16d227Schristos 383bb16d227Schristos /** 0111 110w 1110 1011 ADD.size:G #IMM,sp */ 384bb16d227Schristos 385bb16d227Schristos dc = reg_sd (sp); 386bb16d227Schristos imm = sign_ext (IMM(w), w?16:8); 387bb16d227Schristos MATH_OP (dc, imm, 0, +, > 0xffff); 388bb16d227Schristos 389bb16d227Schristos /** 0111 1101 1011 immm ADD.size:Q #IMM,sp */ 390bb16d227Schristos 391bb16d227Schristos dc = reg_sd (sp); 392bb16d227Schristos imm = sign_ext (immm, 4); 393bb16d227Schristos MATH_OP (dc, imm, 0, +, > 0xffff); 394bb16d227Schristos 395bb16d227Schristos /** 1111 100w immm dest ADJNZ.size #IMM,dest,label */ 396bb16d227Schristos 397bb16d227Schristos UNARY_UOP; 398bb16d227Schristos imm = sign_ext(immm, 4); 399bb16d227Schristos tprintf("%x + %d = %x\n", v, imm, v+imm); 400bb16d227Schristos v += imm; 401bb16d227Schristos put_dest (dc, v); 402bb16d227Schristos a = sign_ext (IMM(0), 8); 403bb16d227Schristos if ((v & (w ? 0xffff : 0xff)) != 0) 404bb16d227Schristos { 405bb16d227Schristos tprintf("jmp: %x + 2 + %d = ", get_reg (pc), a); 406bb16d227Schristos put_reg (pc, orig_pc + 2 + a); 407bb16d227Schristos tprintf("%x\n", get_reg (pc)); 408bb16d227Schristos } 409bb16d227Schristos 410bb16d227Schristos /** 0111 011w 0010 dest AND.size:G #IMM,dest */ 411bb16d227Schristos 412bb16d227Schristos UNARY_UOP; 413bb16d227Schristos imm = IMM(w); 414bb16d227Schristos tprintf ("%x & %x = %x\n", v, imm, v & imm); 415bb16d227Schristos v &= imm; 416bb16d227Schristos set_sz (v, w+1); 417bb16d227Schristos put_dest (dc, v); 418bb16d227Schristos 419bb16d227Schristos /** 1001 0dst AND.B:S #IMM8,dest */ 420bb16d227Schristos 421bb16d227Schristos imm = IMM(0); 422bb16d227Schristos dc = decode_dest3 (dst, 0); 423bb16d227Schristos v = get_src (dc); 424bb16d227Schristos tprintf("%x & %x = %x\n", v, imm, v & imm); 425bb16d227Schristos v &= imm; 426bb16d227Schristos set_sz (v, 1); 427bb16d227Schristos put_dest (dc, v); 428bb16d227Schristos 429bb16d227Schristos /** 1001 000w srcx dest AND.size:G src.dest */ 430bb16d227Schristos 431bb16d227Schristos BINARY_UOP; 432bb16d227Schristos tprintf ("%x & %x = %x\n", a, b, a & b); 433bb16d227Schristos v = a & b; 434bb16d227Schristos set_sz (v, w+1); 435bb16d227Schristos put_dest (dc, v); 436bb16d227Schristos 437bb16d227Schristos /** 0001 0d sr AND.B:S src,R0L/R0H */ 438bb16d227Schristos 439bb16d227Schristos sc = decode_src2 (sr, 0, d); 440bb16d227Schristos dc = decode_dest1 (d, 0); 441bb16d227Schristos a = get_src (sc); 442bb16d227Schristos b = get_src (dc); 443bb16d227Schristos v = a & b; 444bb16d227Schristos tprintf("%x & %x = %x\n", a, b, v); 445bb16d227Schristos set_sz (v, 1); 446bb16d227Schristos put_dest (dc, v); 447bb16d227Schristos 448bb16d227Schristos /** 0111 1110 0100 srcx BAND src */ 449bb16d227Schristos 450bb16d227Schristos BIT_OPC (srcx, b & carry); 451bb16d227Schristos 452bb16d227Schristos /** 0111 1110 1000 dest BCLR:G dest */ 453bb16d227Schristos 454bb16d227Schristos dc = decode_bit (dest); 455bb16d227Schristos put_bit (dc, 0); 456bb16d227Schristos 457bb16d227Schristos /** 0100 0bit BCLR:S bit,base:11[SB] */ 458bb16d227Schristos 459bb16d227Schristos dc = decode_bit11 (bit); 460bb16d227Schristos put_bit (dc, 0); 461bb16d227Schristos 462bb16d227Schristos /** 0111 1110 0010 dest BMcnd dest */ 463bb16d227Schristos 464bb16d227Schristos dc = decode_bit (dest); 465bb16d227Schristos if (condition_true (bmcnd_cond_map [IMM (0) & 15])) 466bb16d227Schristos put_bit (dc, 1); 467bb16d227Schristos else 468bb16d227Schristos put_bit (dc, 0); 469bb16d227Schristos 470bb16d227Schristos /** 0111 1101 1101 cond BMcnd C */ 471bb16d227Schristos 472bb16d227Schristos if (condition_true (cond)) 473bb16d227Schristos set_c (1); 474bb16d227Schristos else 475bb16d227Schristos set_c (0); 476bb16d227Schristos 477bb16d227Schristos /** 0111 1110 0101 srcx BNAND src */ 478bb16d227Schristos 479bb16d227Schristos BIT_OPC (srcx, (!b) & carry); 480bb16d227Schristos 481bb16d227Schristos /** 0111 1110 0111 srcx BNOR src */ 482bb16d227Schristos 483bb16d227Schristos BIT_OPC (srcx, (!b) | carry); 484bb16d227Schristos 485bb16d227Schristos /** 0111 1110 1010 dest BNOT:G dest */ 486bb16d227Schristos 487bb16d227Schristos BIT_OP (dest, !b); 488bb16d227Schristos 489bb16d227Schristos /** 0101 0bit BNOT:S bit,base:11[SB] */ 490bb16d227Schristos 491bb16d227Schristos dc = decode_bit11 (bit); 492bb16d227Schristos put_bit (dc, !get_bit (dc)); 493bb16d227Schristos 494bb16d227Schristos /** 0111 1110 0011 srcx BNTST src */ 495bb16d227Schristos 496bb16d227Schristos dc = decode_bit (srcx); 497bb16d227Schristos b = get_bit (dc); 498bb16d227Schristos set_zc (!b, !b); 499bb16d227Schristos 500bb16d227Schristos /** 0111 1110 1101 srcx BNXOR src */ 501bb16d227Schristos 502bb16d227Schristos BIT_OPC (srcx, !b ^ carry); 503bb16d227Schristos 504bb16d227Schristos /** 0111 1110 0110 srcx BOR src */ 505bb16d227Schristos 506bb16d227Schristos BIT_OPC (srcx, b | carry); 507bb16d227Schristos 508bb16d227Schristos /** 0000 0000 BRK */ 509bb16d227Schristos 510bb16d227Schristos /* We report the break to our caller with the PC still pointing at the 511bb16d227Schristos breakpoint instruction. */ 512bb16d227Schristos put_reg (pc, orig_pc); 513bb16d227Schristos if (verbose) 514bb16d227Schristos printf("[break]\n"); 515bb16d227Schristos return M32C_MAKE_HIT_BREAK (); 516bb16d227Schristos 517bb16d227Schristos /** 0111 1110 1001 dest BSET:G dest */ 518bb16d227Schristos 519bb16d227Schristos dc = decode_bit (dest); 520bb16d227Schristos put_bit (dc, 1); 521bb16d227Schristos 522bb16d227Schristos /** 0100 1bit BSET:S bit,base:11[SB] */ 523bb16d227Schristos 524bb16d227Schristos dc = decode_bit11 (bit); 525bb16d227Schristos put_bit (dc, 1); 526bb16d227Schristos 527bb16d227Schristos /** 0111 1110 1011 srcx BTST:G src */ 528bb16d227Schristos 529bb16d227Schristos dc = decode_bit (srcx); 530bb16d227Schristos b = get_bit (dc); 531bb16d227Schristos set_zc (!b, b); 532bb16d227Schristos 533bb16d227Schristos /** 0101 1bit BTST:S bit,base:11[SB] */ 534bb16d227Schristos 535bb16d227Schristos dc = decode_bit11 (bit); 536bb16d227Schristos b = get_bit (dc); 537bb16d227Schristos set_zc (!b, b); 538bb16d227Schristos 539bb16d227Schristos /** 0111 1110 0000 dest BTSTC dest */ 540bb16d227Schristos 541bb16d227Schristos dc = decode_bit (dest); 542bb16d227Schristos b = get_bit (dc); 543bb16d227Schristos set_zc (!b, b); 544bb16d227Schristos put_bit (dc, 0); 545bb16d227Schristos 546bb16d227Schristos /** 0111 1110 0001 dest BTSTS dest */ 547bb16d227Schristos 548bb16d227Schristos dc = decode_bit (dest); 549bb16d227Schristos b = get_bit (dc); 550bb16d227Schristos set_zc (!b, b); 551bb16d227Schristos put_bit (dc, 1); 552bb16d227Schristos 553bb16d227Schristos /** 0111 1110 1100 srcx BXOR src */ 554bb16d227Schristos 555bb16d227Schristos BIT_OPC (srcx, b ^ carry); 556bb16d227Schristos 557bb16d227Schristos /** 0111 011w 1000 dest CMP.size:G #IMM,dest */ 558bb16d227Schristos 559bb16d227Schristos UNARY_UOP; 560bb16d227Schristos imm = IMM(w); 561bb16d227Schristos cmp (v, imm, w); 562bb16d227Schristos 563bb16d227Schristos /** 1101 000w immm dest CMP.size:Q #IMM,dest */ 564bb16d227Schristos 565bb16d227Schristos UNARY_UOP; 566bb16d227Schristos immm = sign_ext (immm, 4); 567bb16d227Schristos cmp (v, immm, w); 568bb16d227Schristos 569bb16d227Schristos /** 1110 0dst CMP.B:S #IMM8,dest */ 570bb16d227Schristos 571bb16d227Schristos imm = IMM(0); 572bb16d227Schristos dc = decode_dest3 (dst, 0); 573bb16d227Schristos v = get_src (dc); 574bb16d227Schristos cmp (v, imm, 0); 575bb16d227Schristos 576bb16d227Schristos /** 1100 000w srcx dest CMP.size:G src,dest */ 577bb16d227Schristos 578bb16d227Schristos BINARY_UOP; 579bb16d227Schristos cmp(b, a, w); 580bb16d227Schristos 581bb16d227Schristos /** 0011 1d sr CMP.B:S src,R0L/R0H */ 582bb16d227Schristos 583bb16d227Schristos sc = decode_src2 (sr, 0, d); 584bb16d227Schristos dc = decode_dest1 (d, 0); 585bb16d227Schristos a = get_src (sc); 586bb16d227Schristos b = get_src (dc); 587bb16d227Schristos cmp (b, a, 0); 588bb16d227Schristos 589bb16d227Schristos /** 0111 110w 1110 i1c s DADC,DADD,DSBB,DSUB */ 590bb16d227Schristos 591bb16d227Schristos /* w = width, i = immediate, c = carry, s = subtract */ 592bb16d227Schristos 593*8b657b07Schristos { 594bb16d227Schristos int src = i ? IMM(w) : get_reg (w ? r1 : r0h); 595bb16d227Schristos int dest = get_reg (w ? r0 : r0l); 596bb16d227Schristos int res; 597bb16d227Schristos 598bb16d227Schristos src = bcd2int(src, w); 599bb16d227Schristos dest = bcd2int(dest, w); 600bb16d227Schristos 601bb16d227Schristos tprintf("decimal: %d %s %d", dest, s?"-":"+", src); 602bb16d227Schristos if (c) 603bb16d227Schristos tprintf(" c=%d", carry); 604bb16d227Schristos 605bb16d227Schristos if (!s) 606bb16d227Schristos { 607bb16d227Schristos res = dest + src; 608bb16d227Schristos if (c) 609bb16d227Schristos res += carry; 610bb16d227Schristos c = res > (w ? 9999 : 99); 611bb16d227Schristos } 612bb16d227Schristos else 613bb16d227Schristos { 614bb16d227Schristos res = dest - src; 615bb16d227Schristos if (c) 616bb16d227Schristos res -= (1-carry); 617bb16d227Schristos c = res >= 0; 618bb16d227Schristos if (res < 0) 619bb16d227Schristos res += w ? 10000 : 100; 620bb16d227Schristos } 621bb16d227Schristos 622bb16d227Schristos res = int2bcd (res, w); 623bb16d227Schristos tprintf(" = %x\n", res); 624bb16d227Schristos 625bb16d227Schristos set_szc (res, w+1, c); 626bb16d227Schristos 627bb16d227Schristos put_reg (w ? r0 : r0l, res); 628*8b657b07Schristos } 629bb16d227Schristos 630bb16d227Schristos /** 1010 1dst DEC.B dest */ 631bb16d227Schristos 632bb16d227Schristos dc = decode_dest3 (dst, 0); 633bb16d227Schristos v = get_src (dc); 634bb16d227Schristos tprintf("%x -- = %x\n", v, v-1); 635bb16d227Schristos v --; 636bb16d227Schristos set_sz (v, 1); 637bb16d227Schristos put_dest (dc, v); 638bb16d227Schristos 639bb16d227Schristos /** 1111 d010 DEC.W dest */ 640bb16d227Schristos 641bb16d227Schristos v = get_reg (d ? a1 : a0); 642bb16d227Schristos tprintf("%x -- = %x\n", v, v-1); 643bb16d227Schristos v --; 644bb16d227Schristos set_sz (v, 2); 645bb16d227Schristos put_reg (d ? a1 : a0, v); 646bb16d227Schristos 647bb16d227Schristos /** 0111 110w 1110 0001 DIV.size #IMM */ 648bb16d227Schristos 649bb16d227Schristos div_op (-1, 0, 0, w); 650bb16d227Schristos 651bb16d227Schristos /** 0111 011w 1101 srcx DIV.size src */ 652bb16d227Schristos 653bb16d227Schristos div_op (srcx, 0, 0, w); 654bb16d227Schristos 655bb16d227Schristos /** 0111 110w 1110 0000 DIVU.size #IMM */ 656bb16d227Schristos 657bb16d227Schristos div_op (-1, 1, 0, w); 658bb16d227Schristos 659bb16d227Schristos /** 0111 011w 1100 srcx DIVU.size src */ 660bb16d227Schristos 661bb16d227Schristos div_op (srcx, 1, 0, w); 662bb16d227Schristos 663bb16d227Schristos /** 0111 110w 1110 0011 DIVX.size #IMM */ 664bb16d227Schristos 665bb16d227Schristos div_op (-1, 0, 1, w); 666bb16d227Schristos 667bb16d227Schristos /** 0111 011w 1001 srcx DIVX.size src */ 668bb16d227Schristos 669bb16d227Schristos div_op (srcx, 0, 1, w); 670bb16d227Schristos 671bb16d227Schristos /** 0111 1100 1111 0010 ENTER #IMM8 */ 672bb16d227Schristos 673bb16d227Schristos imm = IMM(0); 674bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 675bb16d227Schristos mem_put_hi (get_reg (sp), get_reg (fb)); 676bb16d227Schristos put_reg (fb, get_reg (sp)); 677bb16d227Schristos put_reg (sp, get_reg (sp) - imm); 678bb16d227Schristos 679bb16d227Schristos /** 0111 1101 1111 0010 EXITD */ 680bb16d227Schristos 681bb16d227Schristos put_reg (sp, get_reg (fb)); 682bb16d227Schristos put_reg (fb, mem_get_hi (get_reg (sp))); 683bb16d227Schristos put_reg (sp, get_reg (sp) + 2); 684bb16d227Schristos put_reg (pc, mem_get_psi (get_reg (sp))); 685bb16d227Schristos put_reg (sp, get_reg (sp) + 3); 686bb16d227Schristos 687bb16d227Schristos /** 0111 1100 0110 dest EXTS.B dest */ 688bb16d227Schristos 689bb16d227Schristos dc = decode_srcdest4 (dest, 0); 690bb16d227Schristos v = sign_ext (get_src (dc), 8); 691bb16d227Schristos dc = widen_sd (dc); 692bb16d227Schristos put_dest (dc, v); 693bb16d227Schristos set_sz (v, 1); 694bb16d227Schristos 695bb16d227Schristos /** 0111 1100 1111 0011 EXTS.W R0 */ 696bb16d227Schristos 697bb16d227Schristos v = sign_ext (get_reg (r0), 16); 698bb16d227Schristos put_reg (r2r0, v); 699bb16d227Schristos set_sz (v, 2); 700bb16d227Schristos 701bb16d227Schristos /** 1110 1011 0flg 0101 FCLR dest */ 702bb16d227Schristos 703bb16d227Schristos set_flags (1 << flg, 0); 704bb16d227Schristos 705bb16d227Schristos /** 1110 1011 0flg 0100 FSET dest */ 706bb16d227Schristos 707bb16d227Schristos set_flags (1 << flg, 1 << flg); 708bb16d227Schristos 709bb16d227Schristos /** 1010 0dst INC.B dest */ 710bb16d227Schristos 711bb16d227Schristos dc = decode_dest3 (dst, 0); 712bb16d227Schristos v = get_src (dc); 713bb16d227Schristos tprintf("%x ++ = %x\n", v, v+1); 714bb16d227Schristos v ++; 715bb16d227Schristos set_sz (v, 1); 716bb16d227Schristos put_dest (dc, v); 717bb16d227Schristos 718bb16d227Schristos /** 1011 d010 INC.W dest */ 719bb16d227Schristos 720bb16d227Schristos v = get_reg (d ? a1 : a0); 721bb16d227Schristos tprintf("%x ++ = %x\n", v, v+1); 722bb16d227Schristos v ++; 723bb16d227Schristos set_sz (v, 2); 724bb16d227Schristos put_reg (d ? a1 : a0, v); 725bb16d227Schristos 726bb16d227Schristos /** 1110 1011 11vector INT #imm */ 727bb16d227Schristos 728bb16d227Schristos trigger_based_interrupt (vector); 729bb16d227Schristos 730bb16d227Schristos /** 1111 0110 INTO */ 731bb16d227Schristos 732bb16d227Schristos if (FLAG_O) 733bb16d227Schristos trigger_fixed_interrupt (0xffe0); 734bb16d227Schristos 735bb16d227Schristos /** 0110 1cnd Jcnd label */ 736bb16d227Schristos 737bb16d227Schristos v = sign_ext (IMM(0), 8); 738bb16d227Schristos if (condition_true (cnd)) 739bb16d227Schristos put_reg (pc, orig_pc + 1 + v); 740bb16d227Schristos 741bb16d227Schristos /** 0111 1101 1100 cond Jcnd label */ 742bb16d227Schristos 743bb16d227Schristos v = sign_ext (IMM(0), 8); 744bb16d227Schristos if (condition_true (cond)) 745bb16d227Schristos put_reg (pc, orig_pc + 2 + v); 746bb16d227Schristos 747bb16d227Schristos /** 0110 0dsp JMP.S label */ 748bb16d227Schristos 749bb16d227Schristos put_reg (pc, orig_pc + 2 + dsp); 750bb16d227Schristos 751bb16d227Schristos /** 1111 1110 JMP.B label */ 752bb16d227Schristos 753bb16d227Schristos imm = sign_ext (IMM(0), 8); 754bb16d227Schristos if (imm == -1) 755bb16d227Schristos { 756bb16d227Schristos if (verbose) 757bb16d227Schristos printf("[jmp-to-self detected as exit]\n"); 758bb16d227Schristos return M32C_MAKE_HIT_BREAK (); 759bb16d227Schristos } 760bb16d227Schristos put_reg (pc, orig_pc + 1 + imm); 761bb16d227Schristos 762bb16d227Schristos /** 1111 0100 JMP.W label */ 763bb16d227Schristos 764bb16d227Schristos imm = sign_ext (IMM(1), 16); 765bb16d227Schristos put_reg (pc, orig_pc + 1 + imm); 766bb16d227Schristos 767bb16d227Schristos /** 1111 1100 JMP.A label */ 768bb16d227Schristos 769bb16d227Schristos imm = IMM(2); 770bb16d227Schristos put_reg (pc, imm); 771bb16d227Schristos 772bb16d227Schristos /** 0111 1101 0010 srcx JMPI.W src */ 773bb16d227Schristos 774bb16d227Schristos sc = decode_jumpdest (srcx, 1); 775bb16d227Schristos a = get_src (sc); 776bb16d227Schristos a = sign_ext (a, 16); 777bb16d227Schristos put_reg (pc, orig_pc + a); 778bb16d227Schristos 779bb16d227Schristos /** 0111 1101 0000 srcx JMPI.A src */ 780bb16d227Schristos 781bb16d227Schristos sc = decode_jumpdest (srcx, 0); 782bb16d227Schristos a = get_src (sc); 783bb16d227Schristos put_reg (pc, a); 784bb16d227Schristos 785bb16d227Schristos /** 1110 1110 JMPS #IMM8 */ 786bb16d227Schristos 787bb16d227Schristos M16C_ONLY(); 788bb16d227Schristos 789bb16d227Schristos imm = IMM(0); 790bb16d227Schristos a = 0xf0000 + mem_get_hi (0xffffe - imm * 2); 791bb16d227Schristos put_reg (pc, a); 792bb16d227Schristos 793bb16d227Schristos /** 1111 0101 JSR.W label */ 794bb16d227Schristos 795bb16d227Schristos imm = sign_ext (IMM(1), 16); 796bb16d227Schristos put_reg (sp, get_reg (sp) - 3); 797bb16d227Schristos mem_put_psi (get_reg (sp), get_reg (pc)); 798bb16d227Schristos put_reg (pc, orig_pc + imm + 1); 799bb16d227Schristos 800bb16d227Schristos /** 1111 1101 JSR.A label */ 801bb16d227Schristos 802bb16d227Schristos imm = IMM(2); 803bb16d227Schristos put_reg (sp, get_reg (sp) - 3); 804bb16d227Schristos mem_put_psi (get_reg (sp), get_reg (pc)); 805bb16d227Schristos put_reg (pc, imm); 806bb16d227Schristos 807bb16d227Schristos /** 0111 1101 0011 srcx JSRI.W src */ 808bb16d227Schristos 809bb16d227Schristos sc = decode_jumpdest (srcx, 1); 810bb16d227Schristos a = get_src (sc); 811bb16d227Schristos a = sign_ext (a, 16); 812bb16d227Schristos 813bb16d227Schristos put_reg (sp, get_reg (sp) - 3); 814bb16d227Schristos mem_put_psi (get_reg (sp), get_reg (pc)); 815bb16d227Schristos put_reg (pc, orig_pc + a); 816bb16d227Schristos 817bb16d227Schristos /** 0111 1101 0001 srcx JSRI.A src */ 818bb16d227Schristos 819bb16d227Schristos sc = decode_jumpdest (srcx, 0); 820bb16d227Schristos a = get_src (sc); 821bb16d227Schristos 822bb16d227Schristos put_reg (sp, get_reg (sp) - 3); 823bb16d227Schristos mem_put_psi (get_reg (sp), get_reg (pc)); 824bb16d227Schristos put_reg (pc, a); 825bb16d227Schristos 826bb16d227Schristos /** 1110 1111 JSRS #IMM8 */ 827bb16d227Schristos 828bb16d227Schristos M16C_ONLY(); 829bb16d227Schristos 830bb16d227Schristos imm = IMM(0); 831bb16d227Schristos a = 0xf0000 + mem_get_hi (0xffffe - imm * 2); 832bb16d227Schristos 833bb16d227Schristos put_reg (sp, get_reg (sp) - 3); 834bb16d227Schristos mem_put_psi (get_reg (sp), get_reg (pc)); 835bb16d227Schristos put_reg (pc, a); 836bb16d227Schristos 837bb16d227Schristos /** 1110 1011 0reg 0000 LDC #IMM16,dest */ 838bb16d227Schristos 839bb16d227Schristos dc = decode_cr (reg); 840bb16d227Schristos imm = IMM(1); 841bb16d227Schristos put_dest (dc, imm); 842bb16d227Schristos 843bb16d227Schristos /** 0111 1010 1reg srcx LDC src,dest */ 844bb16d227Schristos 845bb16d227Schristos dc = decode_cr (reg); 846bb16d227Schristos sc = decode_srcdest4 (srcx,1); 847bb16d227Schristos put_dest (dc, get_src (sc)); 848bb16d227Schristos 849bb16d227Schristos /** 0111 1100 1111 0000 LDCTX abs16,abs20 */ 850bb16d227Schristos 851bb16d227Schristos NOTYET(); 852bb16d227Schristos 853bb16d227Schristos /** 0111 010w 1000 dest LDE.size abs20,dest */ 854bb16d227Schristos 855bb16d227Schristos dc = decode_srcdest4 (dest, w); 856bb16d227Schristos imm = IMM(2); 857bb16d227Schristos if (w) 858bb16d227Schristos v = mem_get_hi (imm); 859bb16d227Schristos else 860bb16d227Schristos v = mem_get_qi (imm); 861bb16d227Schristos put_dest (dc, v); 862bb16d227Schristos 863bb16d227Schristos /** 0111 010w 1001 dest LDE.size dsp:20[a0], dest */ 864bb16d227Schristos 865bb16d227Schristos dc = decode_srcdest4 (dest, w); 866bb16d227Schristos imm = IMM(2) + get_reg (a0); 867bb16d227Schristos if (w) 868bb16d227Schristos v = mem_get_hi (imm); 869bb16d227Schristos else 870bb16d227Schristos v = mem_get_qi (imm); 871bb16d227Schristos put_dest (dc, v); 872bb16d227Schristos 873bb16d227Schristos /** 0111 010w 1010 dest LDE.size [a1a0],dest */ 874bb16d227Schristos 875bb16d227Schristos dc = decode_srcdest4 (dest, w); 876bb16d227Schristos imm = get_reg (a1a0); 877bb16d227Schristos if (w) 878bb16d227Schristos v = mem_get_hi (imm); 879bb16d227Schristos else 880bb16d227Schristos v = mem_get_qi (imm); 881bb16d227Schristos put_dest (dc, v); 882bb16d227Schristos 883bb16d227Schristos /** 0111 1101 1010 0imm LDIPL #IMM */ 884bb16d227Schristos 885bb16d227Schristos set_flags (0x700, imm*0x100); 886bb16d227Schristos 887bb16d227Schristos /** 0111 010w 1100 dest MOV.size:G #IMM,dest */ 888bb16d227Schristos 889bb16d227Schristos dc = decode_srcdest4 (dest, w); 890bb16d227Schristos imm = IMM(w); 891bb16d227Schristos v = imm; 892bb16d227Schristos tprintf("%x = %x\n", v, v); 893bb16d227Schristos set_sz(v, w+1); 894bb16d227Schristos put_dest (dc, v); 895bb16d227Schristos 896bb16d227Schristos /** 1101 100w immm dest MOV.size:Q #IMM,dest */ 897bb16d227Schristos 898bb16d227Schristos dc = decode_srcdest4 (dest, w); 899bb16d227Schristos v = sign_ext (immm, 4); 900bb16d227Schristos tprintf ("%x = %x\n", v, v); 901bb16d227Schristos set_sz (v, w+1); 902bb16d227Schristos put_dest (dc, v); 903bb16d227Schristos 904bb16d227Schristos /** 1100 0dst MOV.B:S #IMM8,dest */ 905bb16d227Schristos 906bb16d227Schristos imm = IMM(0); 907bb16d227Schristos dc = decode_dest3 (dst, 0); 908bb16d227Schristos v = imm; 909bb16d227Schristos tprintf("%x = %x\n", v, v); 910bb16d227Schristos set_sz (v, 1); 911bb16d227Schristos put_dest (dc, v); 912bb16d227Schristos 913bb16d227Schristos /** 1w10 d010 MOV.size:S #IMM,dest */ 914bb16d227Schristos 915bb16d227Schristos /* Note that for w, 0=W and 1=B unlike the usual meaning. */ 916bb16d227Schristos v = IMM(1-w); 917bb16d227Schristos tprintf("%x = %x\n", v, v); 918bb16d227Schristos set_sz (v, 2-w); 919bb16d227Schristos put_reg (d ? a1 : a0, v); 920bb16d227Schristos 921bb16d227Schristos /** 1011 0dst MOV.B:Z #0,dest */ 922bb16d227Schristos 923bb16d227Schristos dc = decode_dest3 (dst, 0); 924bb16d227Schristos v = 0; 925bb16d227Schristos set_sz (v, 1); 926bb16d227Schristos put_dest (dc, v); 927bb16d227Schristos 928bb16d227Schristos /** 0111 001w srcx dest MOV.size:G src,dest */ 929bb16d227Schristos 930bb16d227Schristos sc = decode_srcdest4 (srcx, w); 931bb16d227Schristos dc = decode_srcdest4 (dest, w); 932bb16d227Schristos v = get_src (sc); 933bb16d227Schristos set_sz (v, w+1); 934bb16d227Schristos put_dest (dc, v); 935bb16d227Schristos 936bb16d227Schristos /** 0011 0d sr MOV.B:S src,dest */ 937bb16d227Schristos 938bb16d227Schristos sc = decode_src2 (sr, 0, d); 939bb16d227Schristos v = get_src (sc); 940bb16d227Schristos set_sz (v, 1); 941bb16d227Schristos put_reg (d ? a1 : a0, v); 942bb16d227Schristos 943bb16d227Schristos /** 0000 0s ds MOV.B:S R0L/R0H,dest */ 944bb16d227Schristos 945bb16d227Schristos if (ds == 0) 946bb16d227Schristos UNSUPPORTED(); 947bb16d227Schristos dc = decode_src2 (ds, 0, s); 948bb16d227Schristos v = get_reg (s ? r0h : r0l); 949bb16d227Schristos set_sz (v, 1); 950bb16d227Schristos put_dest (dc, v); 951bb16d227Schristos 952bb16d227Schristos /** 0000 1d sr MOV.B:S src,R0L/R0H */ 953bb16d227Schristos 954bb16d227Schristos sc = decode_src2 (sr, 0, d); 955bb16d227Schristos v = get_src (sc); 956bb16d227Schristos set_sz (v, 1); 957bb16d227Schristos put_reg (d ? r0h : r0l, v); 958bb16d227Schristos 959bb16d227Schristos /** 0111 010w 1011 dest MOV.size:G dsp:8[SP], dest */ 960bb16d227Schristos 961bb16d227Schristos dc = decode_srcdest4 (dest, w); 962bb16d227Schristos imm = IMM(0); 963bb16d227Schristos a = get_reg (sp) + sign_ext (imm, 8); 964bb16d227Schristos a &= addr_mask; 965bb16d227Schristos if (w) 966bb16d227Schristos v = mem_get_hi (a); 967bb16d227Schristos else 968bb16d227Schristos v = mem_get_qi (a); 969bb16d227Schristos set_sz (v, w+1); 970bb16d227Schristos put_dest (dc, v); 971bb16d227Schristos 972bb16d227Schristos /** 0111 010w 0011 srcx MOV.size:G src, disp8[SP] */ 973bb16d227Schristos 974bb16d227Schristos sc = decode_srcdest4 (srcx, w); 975bb16d227Schristos imm = IMM(0); 976bb16d227Schristos a = get_reg (sp) + sign_ext (imm, 8); 977bb16d227Schristos a &= addr_mask; 978bb16d227Schristos v = get_src (sc); 979bb16d227Schristos if (w) 980bb16d227Schristos mem_put_hi (a, v); 981bb16d227Schristos else 982bb16d227Schristos mem_put_qi (a, v); 983bb16d227Schristos set_sz (v, w+1); 984bb16d227Schristos 985bb16d227Schristos /** 1110 1011 0reg 1src MOVA src,dest */ 986bb16d227Schristos 987*8b657b07Schristos { 988bb16d227Schristos static reg_id map[] = { r0, r1, r2, r3, a0, a1, 0, 0 }; 989bb16d227Schristos sc = decode_srcdest4 (8 + src, 0); 990bb16d227Schristos put_reg (map[reg], sc.u.addr); 991*8b657b07Schristos } 992bb16d227Schristos 993bb16d227Schristos /** 0111 1100 10hl dest MOVdir R0L,dest */ 994bb16d227Schristos 995bb16d227Schristos if (dest == 0 || dest == 4 || dest == 5) 996bb16d227Schristos UNSUPPORTED(); 997bb16d227Schristos dc = decode_srcdest4 (dest, 0); 998bb16d227Schristos a = get_src (dc); 999bb16d227Schristos b = get_reg (r0l); 1000bb16d227Schristos switch (hl) 1001bb16d227Schristos { 1002bb16d227Schristos case 0: a = (a & 0xf0) | (b & 0x0f); break; 1003bb16d227Schristos case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break; 1004bb16d227Schristos case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break; 1005bb16d227Schristos case 3: a = (a & 0x0f) | (b & 0xf0); break; 1006bb16d227Schristos } 1007bb16d227Schristos put_dest (dc, a); 1008bb16d227Schristos 1009bb16d227Schristos /** 0111 1100 00hl srcx MOVdir src,R0L */ 1010bb16d227Schristos 1011bb16d227Schristos if (srcx == 0 || srcx == 4 || srcx == 5) 1012bb16d227Schristos UNSUPPORTED(); 1013bb16d227Schristos sc = decode_srcdest4 (srcx, 0); 1014bb16d227Schristos a = get_reg (r0l); 1015bb16d227Schristos b = get_src (sc); 1016bb16d227Schristos switch (hl) 1017bb16d227Schristos { 1018bb16d227Schristos case 0: a = (a & 0xf0) | (b & 0x0f); break; 1019bb16d227Schristos case 1: a = (a & 0xf0) | ((b>>4) & 0x0f); break; 1020bb16d227Schristos case 2: a = (a & 0x0f) | ((b & 0x0f)<<4); break; 1021bb16d227Schristos case 3: a = (a & 0x0f) | (b & 0xf0); break; 1022bb16d227Schristos } 1023bb16d227Schristos put_reg (r0l, a); 1024bb16d227Schristos 1025bb16d227Schristos /** 0111 110w 0101 dest MUL.size #IMM,dest */ 1026bb16d227Schristos 1027bb16d227Schristos UNARY_SOP; 1028bb16d227Schristos imm = sign_ext (IMM(w), w?16:8); 1029bb16d227Schristos tprintf("%d * %d = %d\n", v, imm, v*imm); 1030bb16d227Schristos v *= imm; 1031bb16d227Schristos dc = widen_sd (dc); 1032bb16d227Schristos put_dest (dc, v); 1033bb16d227Schristos 1034bb16d227Schristos /** 0111 100w srcx dest MUL.size src,dest */ 1035bb16d227Schristos 1036bb16d227Schristos BINARY_SOP; 1037bb16d227Schristos v = a * b; 1038bb16d227Schristos tprintf("%d * %d = %d\n", a, b, v); 1039bb16d227Schristos dc = widen_sd (dc); 1040bb16d227Schristos put_dest (dc, v); 1041bb16d227Schristos 1042bb16d227Schristos /** 0111 110w 0100 dest MULU.size #IMM,dest */ 1043bb16d227Schristos 1044bb16d227Schristos UNARY_UOP; 1045bb16d227Schristos imm = IMM(w); 1046bb16d227Schristos tprintf("%u * %u = %u\n", v, imm, v*imm); 1047bb16d227Schristos v *= imm; 1048bb16d227Schristos dc = widen_sd (dc); 1049bb16d227Schristos put_dest (dc, v); 1050bb16d227Schristos 1051bb16d227Schristos /** 0111 000w srcx dest MULU.size src,dest */ 1052bb16d227Schristos 1053bb16d227Schristos BINARY_UOP; 1054bb16d227Schristos v = a * b; 1055bb16d227Schristos tprintf("%u * %u = %u\n", a, b, v); 1056bb16d227Schristos dc = widen_sd (dc); 1057bb16d227Schristos put_dest (dc, v); 1058bb16d227Schristos 1059bb16d227Schristos /** 0111 010w 0101 dest NEG.size dest */ 1060bb16d227Schristos 1061bb16d227Schristos UNARY_SOP; 1062bb16d227Schristos tprintf("%d * -1 = %d\n", v, -v); 1063bb16d227Schristos v = -v; 1064bb16d227Schristos set_oszc (v, w+1, v == 0); 1065bb16d227Schristos put_dest (dc, v); 1066bb16d227Schristos 1067bb16d227Schristos /** 0000 0100 NOP */ 1068bb16d227Schristos 1069bb16d227Schristos tprintf("nop\n"); 1070bb16d227Schristos 1071bb16d227Schristos /** 0111 010w 0111 dest NOT.size:G */ 1072bb16d227Schristos 1073bb16d227Schristos UNARY_UOP; 1074bb16d227Schristos tprintf("~ %x = %x\n", v, ~v); 1075bb16d227Schristos v = ~v; 1076bb16d227Schristos set_sz (v, w+1); 1077bb16d227Schristos put_dest (dc, v); 1078bb16d227Schristos 1079bb16d227Schristos /** 1011 1dst NOT.B:S dest */ 1080bb16d227Schristos 1081bb16d227Schristos dc = decode_dest3 (dst, 0); 1082bb16d227Schristos v = get_src (dc); 1083bb16d227Schristos tprintf("~ %x = %x\n", v, ~v); 1084bb16d227Schristos v = ~v; 1085bb16d227Schristos set_sz (v, 1); 1086bb16d227Schristos put_dest (dc, v); 1087bb16d227Schristos 1088bb16d227Schristos /** 0111 011w 0011 dest OR.size:G #IMM,dest */ 1089bb16d227Schristos 1090bb16d227Schristos UNARY_UOP; 1091bb16d227Schristos imm = IMM(w); 1092bb16d227Schristos tprintf ("%x | %x = %x\n", v, imm, v | imm); 1093bb16d227Schristos v |= imm; 1094bb16d227Schristos set_sz (v, w+1); 1095bb16d227Schristos put_dest (dc, v); 1096bb16d227Schristos 1097bb16d227Schristos /** 1001 1dst OR.B:S #IMM8,dest */ 1098bb16d227Schristos 1099bb16d227Schristos imm = IMM(0); 1100bb16d227Schristos dc = decode_dest3 (dst, 0); 1101bb16d227Schristos v = get_src (dc); 1102bb16d227Schristos tprintf("%x | %x = %x\n", v, imm, v|imm); 1103bb16d227Schristos v |= imm; 1104bb16d227Schristos set_sz (v, 1); 1105bb16d227Schristos put_dest (dc, v); 1106bb16d227Schristos 1107bb16d227Schristos /** 1001 100w srcx dest OR.size:G src,dest */ 1108bb16d227Schristos 1109bb16d227Schristos BINARY_UOP; 1110bb16d227Schristos tprintf ("%x | %x = %x\n", a, b, a | b); 1111bb16d227Schristos v = a | b; 1112bb16d227Schristos set_sz (v, w+1); 1113bb16d227Schristos put_dest (dc, v); 1114bb16d227Schristos 1115bb16d227Schristos /** 0001 1d sr OR.B:S src,R0L/R0H */ 1116bb16d227Schristos 1117bb16d227Schristos sc = decode_src2 (sr, 0, d); 1118bb16d227Schristos dc = decode_dest1 (d, 0); 1119bb16d227Schristos a = get_src (sc); 1120bb16d227Schristos b = get_src (dc); 1121bb16d227Schristos v = a | b; 1122bb16d227Schristos tprintf("%x | %x = %x\n", a, b, v); 1123bb16d227Schristos set_sz (v, 1); 1124bb16d227Schristos put_dest (dc, v); 1125bb16d227Schristos 1126bb16d227Schristos /** 0111 010w 1101 dest POP.size:G dest */ 1127bb16d227Schristos 1128bb16d227Schristos dc = decode_srcdest4 (dest, w); 1129bb16d227Schristos if (w) 1130bb16d227Schristos { 1131bb16d227Schristos v = mem_get_hi (get_reg (sp)); 1132bb16d227Schristos put_reg (sp, get_reg (sp) + 2); 1133bb16d227Schristos tprintf("pophi: %x\n", v); 1134bb16d227Schristos } 1135bb16d227Schristos else 1136bb16d227Schristos { 1137bb16d227Schristos v = mem_get_qi (get_reg (sp)); 1138bb16d227Schristos put_reg (sp, get_reg (sp) + 1); 1139bb16d227Schristos tprintf("popqi: %x\n", v); 1140bb16d227Schristos } 1141bb16d227Schristos put_dest (dc, v); 1142bb16d227Schristos 1143bb16d227Schristos /** 1001 d010 POP.B:S dest */ 1144bb16d227Schristos 1145bb16d227Schristos v = mem_get_qi (get_reg (sp)); 1146bb16d227Schristos put_reg (d ? r0h : r0l, v); 1147bb16d227Schristos put_reg (sp, get_reg (sp) + 1); 1148bb16d227Schristos tprintf("popqi: %x\n", v); 1149bb16d227Schristos 1150bb16d227Schristos /** 1101 d010 POP.W:S dest */ 1151bb16d227Schristos 1152bb16d227Schristos v = mem_get_hi (get_reg (sp)); 1153bb16d227Schristos put_reg (d ? a1 : a0, v); 1154bb16d227Schristos put_reg (sp, get_reg (sp) + 2); 1155bb16d227Schristos tprintf("pophi: %x\n", v); 1156bb16d227Schristos 1157bb16d227Schristos /** 1110 1011 0reg 0011 POPC dest */ 1158bb16d227Schristos 1159bb16d227Schristos dc = decode_cr (reg); 1160bb16d227Schristos v = mem_get_hi (get_reg (sp)); 1161bb16d227Schristos put_dest (dc, v); 1162bb16d227Schristos put_reg (sp, get_reg (sp) + 2); 1163bb16d227Schristos tprintf("popc: %x\n", v); 1164bb16d227Schristos 1165bb16d227Schristos /** 1110 1101 POPM dest */ 1166bb16d227Schristos 1167*8b657b07Schristos { 1168bb16d227Schristos static int map[] = { r0, r1, r2, r3, a0, a1, sb, fb }; 1169bb16d227Schristos imm = IMM(0); 1170bb16d227Schristos tprintf("popm: %x\n", imm); 1171bb16d227Schristos for (a=0; a<8; a++) 1172bb16d227Schristos if (imm & (1<<a)) 1173bb16d227Schristos { 1174bb16d227Schristos v = mem_get_hi (get_reg (sp)); 1175bb16d227Schristos put_reg (map[a], v); 1176bb16d227Schristos put_reg (sp, get_reg (sp) + 2); 1177bb16d227Schristos } 1178*8b657b07Schristos } 1179bb16d227Schristos 1180bb16d227Schristos /** 0111 110w 1110 0010 PUSH.size:G #IMM */ 1181bb16d227Schristos 1182bb16d227Schristos imm = IMM(w); 1183bb16d227Schristos if (w) 1184bb16d227Schristos { 1185bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1186bb16d227Schristos mem_put_hi (get_reg (sp), imm); 1187bb16d227Schristos tprintf("pushhi %04x\n", imm); 1188bb16d227Schristos } 1189bb16d227Schristos else 1190bb16d227Schristos { 1191bb16d227Schristos put_reg (sp, get_reg (sp) - 1); 1192bb16d227Schristos mem_put_qi (get_reg (sp), imm); 1193bb16d227Schristos tprintf("pushqi %02x\n", imm); 1194bb16d227Schristos } 1195bb16d227Schristos 1196bb16d227Schristos /** 0111 010w 0100 srcx PUSH.size:G src */ 1197bb16d227Schristos 1198bb16d227Schristos sc = decode_srcdest4 (srcx, w); 1199bb16d227Schristos v = get_src (sc); 1200bb16d227Schristos if (w) 1201bb16d227Schristos { 1202bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1203bb16d227Schristos mem_put_hi (get_reg (sp), v); 1204bb16d227Schristos tprintf("pushhi: %x\n", v); 1205bb16d227Schristos } 1206bb16d227Schristos else 1207bb16d227Schristos { 1208bb16d227Schristos put_reg (sp, get_reg (sp) - 1); 1209bb16d227Schristos mem_put_qi (get_reg (sp), v); 1210bb16d227Schristos tprintf("pushqi: %x\n", v); 1211bb16d227Schristos } 1212bb16d227Schristos 1213bb16d227Schristos /** 1000 s010 PUSH.B:S src */ 1214bb16d227Schristos 1215bb16d227Schristos v = get_reg (s ? r0h : r0l); 1216bb16d227Schristos put_reg (sp, get_reg (sp) - 1); 1217bb16d227Schristos mem_put_qi (get_reg (sp), v); 1218bb16d227Schristos tprintf("pushqi: %x\n", v); 1219bb16d227Schristos 1220bb16d227Schristos /** 1100 s010 PUSH.W:S src */ 1221bb16d227Schristos 1222bb16d227Schristos v = get_reg (s ? a1 : a0); 1223bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1224bb16d227Schristos mem_put_hi (get_reg (sp), v); 1225bb16d227Schristos tprintf("pushhi: %x\n", v); 1226bb16d227Schristos 1227bb16d227Schristos /** 0111 1101 1001 srcx PUSHA src */ 1228bb16d227Schristos 1229bb16d227Schristos sc = decode_srcdest4 (srcx, 0); 1230bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1231bb16d227Schristos mem_put_hi (get_reg (sp), sc.u.addr); 1232bb16d227Schristos tprintf("pushhi: %x\n", sc.u.addr); 1233bb16d227Schristos 1234bb16d227Schristos /** 1110 1011 0src 0010 PUSHC src */ 1235bb16d227Schristos 1236bb16d227Schristos sc = decode_cr (src); 1237bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1238bb16d227Schristos v = get_src (sc); 1239bb16d227Schristos mem_put_hi (get_reg (sp), v); 1240bb16d227Schristos tprintf("pushc: %x\n", v); 1241bb16d227Schristos 1242bb16d227Schristos /** 1110 1100 PUSHM src */ 1243bb16d227Schristos 1244*8b657b07Schristos { 1245bb16d227Schristos static int map[] = { fb, sb, a1, a0, r3, r2, r1, r0 }; 1246bb16d227Schristos imm = IMM(0); 1247bb16d227Schristos tprintf("pushm: %x\n", imm); 1248bb16d227Schristos for (a=0; a<8; a++) 1249bb16d227Schristos if (imm & (1<<a)) 1250bb16d227Schristos { 1251bb16d227Schristos put_reg (sp, get_reg (sp) - 2); 1252bb16d227Schristos v = get_reg (map[a]); 1253bb16d227Schristos mem_put_hi (get_reg (sp), v); 1254bb16d227Schristos } 1255*8b657b07Schristos } 1256bb16d227Schristos 1257bb16d227Schristos /** 1111 1011 REIT */ 1258bb16d227Schristos 1259bb16d227Schristos a = get_reg (sp); 1260bb16d227Schristos v = (mem_get_hi (a) 1261bb16d227Schristos + 4096 * (mem_get_qi (a+3) & 0xf0)); 1262bb16d227Schristos b = (mem_get_qi (a+2) 1263bb16d227Schristos + 256 * (mem_get_qi (a+3) & 0xff)); 1264bb16d227Schristos put_reg (pc, v); 1265bb16d227Schristos put_reg (flags, b); 1266bb16d227Schristos put_reg (sp, get_reg (sp) + 4); 1267bb16d227Schristos 1268bb16d227Schristos /** 0111 110w 1111 0001 RMPA.size */ 1269bb16d227Schristos 1270*8b657b07Schristos { 1271bb16d227Schristos int count = get_reg (r3); 1272bb16d227Schristos int list1 = get_reg (a0); 1273bb16d227Schristos int list2 = get_reg (a1); 1274bb16d227Schristos int sum = get_reg (w ? r2r0 : r0); 1275bb16d227Schristos 1276bb16d227Schristos while (count) 1277bb16d227Schristos { 1278bb16d227Schristos if (w) 1279bb16d227Schristos { 1280bb16d227Schristos a = sign_ext (mem_get_hi (list1), 16); 1281bb16d227Schristos b = sign_ext (mem_get_hi (list2), 16); 1282bb16d227Schristos } 1283bb16d227Schristos else 1284bb16d227Schristos { 1285bb16d227Schristos a = sign_ext (mem_get_qi (list1), 8); 1286bb16d227Schristos b = sign_ext (mem_get_qi (list2), 8); 1287bb16d227Schristos } 1288bb16d227Schristos tprintf("%d + %d * %d = ", sum, a, b); 1289bb16d227Schristos sum += a * b; 1290bb16d227Schristos tprintf("%d\n", sum); 1291bb16d227Schristos list1 += w ? 2 : 1; 1292bb16d227Schristos list2 += w ? 2 : 1; 1293bb16d227Schristos count --; 1294bb16d227Schristos } 1295bb16d227Schristos put_reg (r3, count); 1296bb16d227Schristos put_reg (a0, list1); 1297bb16d227Schristos put_reg (a1, list2); 1298bb16d227Schristos put_reg (w ? r2r0 : r0, sum); 1299*8b657b07Schristos } 1300bb16d227Schristos 1301bb16d227Schristos /** 0111 011w 1010 dest ROLC.size dest */ 1302bb16d227Schristos 1303bb16d227Schristos dc = decode_srcdest4 (dest, w); 1304bb16d227Schristos rot_op (dc, 1, 1); 1305bb16d227Schristos 1306bb16d227Schristos /** 0111 011w 1011 dest RORC.size dest */ 1307bb16d227Schristos 1308bb16d227Schristos dc = decode_srcdest4 (dest, w); 1309bb16d227Schristos rot_op (dc, 1, -1); 1310bb16d227Schristos 1311bb16d227Schristos /** 1110 000w immm dest ROT.size #IMM,dest */ 1312bb16d227Schristos 1313bb16d227Schristos dc = decode_srcdest4 (dest, w); 1314bb16d227Schristos rot_op (dc, 0, IMM4()); 1315bb16d227Schristos 1316bb16d227Schristos /** 0111 010w 0110 dest ROT.size R1H,dest */ 1317bb16d227Schristos 1318bb16d227Schristos dc = decode_srcdest4 (dest, w); 1319bb16d227Schristos rot_op (dc, 0, sign_ext (get_reg (r1h), 8)); 1320bb16d227Schristos 1321bb16d227Schristos /** 1111 0011 RTS */ 1322bb16d227Schristos 1323bb16d227Schristos put_reg (pc, mem_get_psi (get_reg (sp))); 1324bb16d227Schristos put_reg (sp, get_reg (sp) + 3); 1325bb16d227Schristos 1326bb16d227Schristos /** 0111 011w 0111 dest SBB.size #IMM,dest */ 1327bb16d227Schristos 1328bb16d227Schristos dc = decode_srcdest4 (dest, w); 1329bb16d227Schristos imm = IMM(w); 1330bb16d227Schristos MATH_OP (dc, imm, !carry, -, >= 0); 1331bb16d227Schristos 1332bb16d227Schristos /** 1011 100w srcx dest SBB.size src,dest */ 1333bb16d227Schristos 1334bb16d227Schristos sc = decode_srcdest4(srcx, w); 1335bb16d227Schristos dc = decode_srcdest4(dest, w); 1336bb16d227Schristos b = get_src (sc); 1337bb16d227Schristos MATH_OP (dc, b, !carry, -, >= 0); 1338bb16d227Schristos 1339bb16d227Schristos /** 1111 000w immm dest SHA.size #IMM, dest */ 1340bb16d227Schristos 1341bb16d227Schristos dc = decode_srcdest4(dest, w); 1342bb16d227Schristos shift_op (dc, 1, IMM4()); 1343bb16d227Schristos 1344bb16d227Schristos /** 0111 010w 1111 dest SHA.size R1H,dest */ 1345bb16d227Schristos 1346bb16d227Schristos dc = decode_srcdest4(dest, w); 1347bb16d227Schristos a = sign_ext (get_reg (r1h), 8); 1348bb16d227Schristos shift_op (dc, 1, a); 1349bb16d227Schristos 1350bb16d227Schristos /** 1110 1011 101d immm SHA.L #IMM, dest */ 1351bb16d227Schristos 1352bb16d227Schristos dc = reg_sd (d ? r3r1 : r2r0); 1353bb16d227Schristos shift_op (dc, 1, IMM4()); 1354bb16d227Schristos 1355bb16d227Schristos /** 1110 1011 001d 0001 SHA.L R1H,dest */ 1356bb16d227Schristos 1357bb16d227Schristos dc = reg_sd (d ? r3r1 : r2r0); 1358bb16d227Schristos a = sign_ext (get_reg (r1h), 8); 1359bb16d227Schristos shift_op (dc, 1, a); 1360bb16d227Schristos 1361bb16d227Schristos /** 1110 100w immm dest SHL.size #IMM, dest */ 1362bb16d227Schristos 1363bb16d227Schristos dc = decode_srcdest4(dest, w); 1364bb16d227Schristos shift_op (dc, 0, IMM4()); 1365bb16d227Schristos 1366bb16d227Schristos /** 0111 010w 1110 dest SHL.size R1H,dest */ 1367bb16d227Schristos 1368bb16d227Schristos dc = decode_srcdest4(dest, w); 1369bb16d227Schristos a = sign_ext (get_reg (r1h), 8); 1370bb16d227Schristos shift_op (dc, 0, a); 1371bb16d227Schristos 1372bb16d227Schristos /** 1110 1011 100d immm SHL.L #IMM,dest */ 1373bb16d227Schristos 1374bb16d227Schristos dc = reg_sd (d ? r3r1 : r2r0); 1375bb16d227Schristos shift_op (dc, 0, IMM4()); 1376bb16d227Schristos 1377bb16d227Schristos /** 1110 1011 000d 0001 SHL.L R1H,dest */ 1378bb16d227Schristos 1379bb16d227Schristos dc = reg_sd (d ? r3r1 : r2r0); 1380bb16d227Schristos a = sign_ext (get_reg (r1h), 8); 1381bb16d227Schristos shift_op (dc, 0, a); 1382bb16d227Schristos 1383bb16d227Schristos /** 0111 110w 1110 100b SMOVB.size */ 1384bb16d227Schristos 1385*8b657b07Schristos { 1386bb16d227Schristos int count = get_reg (r3); 1387bb16d227Schristos int s1 = get_reg (a0) + (get_reg (r1h) << 16); 1388bb16d227Schristos int s2 = get_reg (a1); 1389bb16d227Schristos int inc = (w ? 2 : 1) * (b ? -1 : 1); 1390bb16d227Schristos 1391bb16d227Schristos while (count) 1392bb16d227Schristos { 1393bb16d227Schristos if (w) 1394bb16d227Schristos { 1395bb16d227Schristos v = mem_get_hi (s1); 1396bb16d227Schristos mem_put_hi (s2, v); 1397bb16d227Schristos } 1398bb16d227Schristos else 1399bb16d227Schristos { 1400bb16d227Schristos v = mem_get_qi (s1); 1401bb16d227Schristos mem_put_qi (s2, v); 1402bb16d227Schristos } 1403bb16d227Schristos s1 += inc; 1404bb16d227Schristos s2 += inc; 1405bb16d227Schristos count --; 1406bb16d227Schristos } 1407bb16d227Schristos put_reg (r3, count); 1408bb16d227Schristos put_reg (a0, s1 & 0xffff); 1409bb16d227Schristos put_reg (a1, s2); 1410bb16d227Schristos put_reg (r1h, s1 >> 16); 1411*8b657b07Schristos } 1412bb16d227Schristos 1413bb16d227Schristos /** 0111 110w 1110 1010 SSTR.size */ 1414bb16d227Schristos 1415*8b657b07Schristos { 1416bb16d227Schristos int count = get_reg (r3); 1417bb16d227Schristos int s1 = get_reg (a1); 1418bb16d227Schristos v = get_reg (w ? r0 : r0l); 1419bb16d227Schristos 1420bb16d227Schristos while (count) 1421bb16d227Schristos { 1422bb16d227Schristos if (w) 1423bb16d227Schristos { 1424bb16d227Schristos mem_put_hi (s1, v); 1425bb16d227Schristos s1 += 2; 1426bb16d227Schristos } 1427bb16d227Schristos else 1428bb16d227Schristos { 1429bb16d227Schristos mem_put_qi (s1, v); 1430bb16d227Schristos s1 += 1; 1431bb16d227Schristos } 1432bb16d227Schristos count --; 1433bb16d227Schristos } 1434bb16d227Schristos put_reg (r3, count); 1435bb16d227Schristos put_reg (a1, s1); 1436*8b657b07Schristos } 1437bb16d227Schristos 1438bb16d227Schristos /** 0111 1011 1src dest STC src,dest */ 1439bb16d227Schristos 1440bb16d227Schristos dc = decode_srcdest4 (dest, 1); 1441bb16d227Schristos sc = decode_cr (src); 1442bb16d227Schristos put_dest (dc, get_src(sc)); 1443bb16d227Schristos 1444bb16d227Schristos /** 0111 1100 1100 dest STC PC,dest */ 1445bb16d227Schristos 1446bb16d227Schristos dc = decode_srcdest4 (dest, 1); 1447bb16d227Schristos dc.bytes = 3; 1448bb16d227Schristos put_dest (dc, orig_pc); 1449bb16d227Schristos 1450bb16d227Schristos /** 0111 1101 1111 0000 STCTX abs16,abs20 */ 1451bb16d227Schristos 1452bb16d227Schristos NOTYET(); 1453bb16d227Schristos 1454bb16d227Schristos /** 0111 010w 0000 srcx STE.size src,abs20 */ 1455bb16d227Schristos 1456bb16d227Schristos sc = decode_srcdest4 (srcx, w); 1457bb16d227Schristos a = IMM(2); 1458bb16d227Schristos v = get_src (sc); 1459bb16d227Schristos if (w) 1460bb16d227Schristos mem_put_hi (a, v); 1461bb16d227Schristos else 1462bb16d227Schristos mem_put_qi (a, v); 1463bb16d227Schristos if (srcx == 4 || srcx == 5) 1464bb16d227Schristos { 1465bb16d227Schristos v = get_reg (sc.u.reg); 1466bb16d227Schristos set_sz (v, 2); 1467bb16d227Schristos } 1468bb16d227Schristos else 1469bb16d227Schristos set_sz (v, w+1); 1470bb16d227Schristos 1471bb16d227Schristos /** 0111 010w 0001 srcx STE.size src,disp20[a0] */ 1472bb16d227Schristos 1473bb16d227Schristos sc = decode_srcdest4 (srcx, w); 1474bb16d227Schristos a = get_reg(a0) + IMM(2); 1475bb16d227Schristos v = get_src (sc); 1476bb16d227Schristos if (w) 1477bb16d227Schristos mem_put_hi (a, v); 1478bb16d227Schristos else 1479bb16d227Schristos mem_put_qi (a, v); 1480bb16d227Schristos if (srcx == 4 || srcx == 5) 1481bb16d227Schristos { 1482bb16d227Schristos v = get_reg (sc.u.reg); 1483bb16d227Schristos set_sz (v, 2); 1484bb16d227Schristos } 1485bb16d227Schristos else 1486bb16d227Schristos set_sz (v, w+1); 1487bb16d227Schristos 1488bb16d227Schristos /** 0111 010w 0010 srcx STE.size src,[a1a0] */ 1489bb16d227Schristos 1490bb16d227Schristos sc = decode_srcdest4 (srcx, w); 1491bb16d227Schristos a = get_reg(a1a0); 1492bb16d227Schristos v = get_src (sc); 1493bb16d227Schristos if (w) 1494bb16d227Schristos mem_put_hi (a, v); 1495bb16d227Schristos else 1496bb16d227Schristos mem_put_qi (a, v); 1497bb16d227Schristos if (srcx == 4 || srcx == 5) 1498bb16d227Schristos { 1499bb16d227Schristos v = get_reg (sc.u.reg); 1500bb16d227Schristos set_sz (v, 2); 1501bb16d227Schristos } 1502bb16d227Schristos else 1503bb16d227Schristos set_sz (v, w+1); 1504bb16d227Schristos 1505bb16d227Schristos /** 1101 0dst STNZ #IMM8,dest */ 1506bb16d227Schristos 1507bb16d227Schristos imm = IMM(0); 1508bb16d227Schristos dc = decode_dest3(dst, 0); 1509bb16d227Schristos if (!FLAG_Z) 1510bb16d227Schristos put_dest (dc, imm); 1511bb16d227Schristos 1512bb16d227Schristos /** 1100 1dst STZ #IMM8,dest */ 1513bb16d227Schristos 1514bb16d227Schristos imm = IMM(0); 1515bb16d227Schristos dc = decode_dest3(dst, 0); 1516bb16d227Schristos if (FLAG_Z) 1517bb16d227Schristos put_dest (dc, imm); 1518bb16d227Schristos 1519bb16d227Schristos /** 1101 1dst STZX #IMM81,#IMM82,dest */ 1520bb16d227Schristos 1521bb16d227Schristos a = IMM(0); 1522bb16d227Schristos dc = decode_dest3(dst, 0); 1523bb16d227Schristos b = IMM(0); 1524bb16d227Schristos if (FLAG_Z) 1525bb16d227Schristos put_dest (dc, a); 1526bb16d227Schristos else 1527bb16d227Schristos put_dest (dc, b); 1528bb16d227Schristos 1529bb16d227Schristos /** 0111 011w 0101 dest SUB.size:G #IMM,dest */ 1530bb16d227Schristos 1531bb16d227Schristos dc = decode_srcdest4 (dest, w); 1532bb16d227Schristos imm = IMM(w); 1533bb16d227Schristos MATH_OP (dc, imm, 0, -, >= 0); 1534bb16d227Schristos 1535bb16d227Schristos /** 1000 1dst SUB.B:S #IMM8,dest */ 1536bb16d227Schristos 1537bb16d227Schristos imm = IMM(0); 1538bb16d227Schristos dc = decode_dest3 (dst, 0); 1539bb16d227Schristos MATH_OP (dc, imm, 0, -, >= 0); 1540bb16d227Schristos 1541bb16d227Schristos /** 1010 100w srcx dest SUB.size:G src,dest */ 1542bb16d227Schristos 1543bb16d227Schristos sc = decode_srcdest4(srcx, w); 1544bb16d227Schristos dc = decode_srcdest4(dest, w); 1545bb16d227Schristos b = get_src (sc); 1546bb16d227Schristos MATH_OP (dc, b, 0, -, >= 0); 1547bb16d227Schristos 1548bb16d227Schristos /** 0010 1d sr SUB.B:S src,R0L/R0H */ 1549bb16d227Schristos 1550bb16d227Schristos sc = decode_src2 (sr, 0, d); 1551bb16d227Schristos dc = decode_dest1 (d, 0); 1552bb16d227Schristos b = get_src (sc); 1553bb16d227Schristos MATH_OP (dc, b, 0, -, >= 0); 1554bb16d227Schristos 1555bb16d227Schristos /** 0111 011w 0000 dest TST.size #IMM, dest */ 1556bb16d227Schristos 1557bb16d227Schristos UNARY_UOP; 1558bb16d227Schristos imm = IMM(w); 1559bb16d227Schristos tprintf ("%x & %x = %x\n", v, imm, v & imm); 1560bb16d227Schristos v &= imm; 1561bb16d227Schristos set_sz (v, w+1); 1562bb16d227Schristos 1563bb16d227Schristos /** 1000 000w srcx dest TST.size src,dest */ 1564bb16d227Schristos 1565bb16d227Schristos BINARY_UOP; 1566bb16d227Schristos tprintf ("%x & %x = %x\n", a, b, a & b); 1567bb16d227Schristos v = a & b; 1568bb16d227Schristos set_sz (v, w+1); 1569bb16d227Schristos 1570bb16d227Schristos /** 1111 1111 UND */ 1571bb16d227Schristos 1572bb16d227Schristos trigger_fixed_interrupt (0xffdc); 1573bb16d227Schristos 1574bb16d227Schristos /** 0111 1101 1111 0011 WAIT */ 1575bb16d227Schristos 1576bb16d227Schristos tprintf("waiting...\n"); 1577bb16d227Schristos 1578bb16d227Schristos /** 0111 101w 00sr dest XCHG.size src,dest */ 1579bb16d227Schristos 1580bb16d227Schristos sc = decode_srcdest4 (sr, w); 1581bb16d227Schristos dc = decode_srcdest4 (dest, w); 1582bb16d227Schristos a = get_src (sc); 1583bb16d227Schristos b = get_src (dc); 1584bb16d227Schristos put_dest (dc, a); 1585bb16d227Schristos put_dest (sc, b); 1586bb16d227Schristos 1587bb16d227Schristos /** 0111 011w 0001 dest XOR.size #IMM,dest */ 1588bb16d227Schristos 1589bb16d227Schristos UNARY_UOP; 1590bb16d227Schristos imm = IMM(w); 1591bb16d227Schristos tprintf ("%x ^ %x = %x\n", v, imm, v ^ imm); 1592bb16d227Schristos v ^= imm; 1593bb16d227Schristos set_sz (v, w+1); 1594bb16d227Schristos put_dest (dc, v); 1595bb16d227Schristos 1596bb16d227Schristos /** 1000 100w srcx dest XOR.size src,dest */ 1597bb16d227Schristos 1598bb16d227Schristos BINARY_UOP; 1599bb16d227Schristos tprintf ("%x ^ %x = %x\n", a, b, a ^ b); 1600bb16d227Schristos v = a ^ b; 1601bb16d227Schristos set_sz (v, w+1); 1602bb16d227Schristos put_dest (dc, v); 1603bb16d227Schristos 1604bb16d227Schristos /** OP */ 1605bb16d227Schristos/** */ 1606bb16d227Schristos 1607bb16d227Schristos return step_result; 1608bb16d227Schristos} 1609