X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fv850%2Fv850.igen;h=41a9075a8e79448ee9bfb22422f5bb20bd1916a9;hb=22aa1d51198689f5f3f01a874b405bf4449cbfb0;hp=eb7451a9c5cfc95e151fd894417cd222f7a89c44;hpb=6aead89a5fa550f1845fb5b3c85f50e53afb6f92;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/v850/v850.igen b/sim/v850/v850.igen index eb7451a9c5..41a9075a8e 100644 --- a/sim/v850/v850.igen +++ b/sim/v850/v850.igen @@ -1,85 +1,92 @@ -:option::insn-bit-size:16 -:option::hi-bit-nr:15 +:option:::insn-bit-size:16 +:option:::hi-bit-nr:15 -:option::format-names:I,II,III,IV,V,VI,VII,VIII,IX,X -# start-sanitize-v850e -:option::format-names:XI,XII,XIII -# end-sanitize-v850e -# start-sanitize-v850eq -:option::format-names:XIV,XV -# end-sanitize-v850eq -:option::format-names:Z +:option:::format-names:I,II,III,IV,V,VI,VII,VIII,IX,X +:option:::format-names:XI,XII,XIII +:option:::format-names:XIV,XV +:option:::format-names:Z +:option:::format-names:F_I +:option:::format-names:C -:model::v850:v850: - -# start-sanitize-v850e -:option::multi-sim:true -:model::v850e:v850e: -# end-sanitize-v850e - -# start-sanitize-v850eq -:option::multi-sim:true -:model::v850eq:v850eq: -# end-sanitize-v850eq - +:model:::v850:v850: +:option:::multi-sim:true +:model:::v850e:v850e: +:option:::multi-sim:true +:model:::v850e1:v850e1: +:option:::multi-sim:true +:model:::v850e2:v850e2: +:option:::multi-sim:true +:model:::v850e2v3:v850e2v3: +:option:::multi-sim:true +:model:::v850e3v5:v850e3v5: // Cache macros -:cache::unsigned:reg1:RRRRR:(RRRRR) -:cache::unsigned:reg2:rrrrr:(rrrrr) -:cache::unsigned:reg3:wwwww:(wwwww) - -:cache::unsigned:disp4:dddd:(dddd) -# start-sanitize-v850e -:cache::unsigned:disp5:dddd:(dddd << 1) -# end-sanitize-v850e -:cache::unsigned:disp7:ddddddd:ddddddd -:cache::unsigned:disp8:ddddddd:(ddddddd << 1) -:cache::unsigned:disp8:dddddd:(dddddd << 2) -:cache::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1) -:cache::unsigned:disp16:dddddddddddddddd:SEXT32 (dddddddddddddddd, 16 - 1) -:cache::unsigned:disp16:ddddddddddddddd:SEXT32 (ddddddddddddddd << 1, 16 - 1) -:cache::unsigned:disp22:dddddd,dddddddddddddddd:SEXT32 ((dddddd << 16) + (dddddddddddddddd << 1), 22 - 1) -:cache::unsigned:disp22:dddddd,ddddddddddddddd:SEXT32 ((dddddd << 16) + (ddddddddddddddd << 2), 22 - 1) - -:cache::unsigned:imm5:iiiii:SEXT32 (iiiii, 4) -:cache::unsigned:imm6:iiiiii:iiiiii -:cache::unsigned:imm9:iiiii,IIII:SEXT ((IIII << 5) + iiiii, 9 - 1) -# start-sanitize-v850eq -:cache::unsigned:imm5:iiii:(32 - (iiii << 1)) -# end-sanitize-v850eq -:cache::unsigned:simm16:iiiiiiiiiiiiiiii:EXTEND16 (iiiiiiiiiiiiiiii) -:cache::unsigned:uimm16:iiiiiiiiiiiiiiii:iiiiiiiiiiiiiiii -:cache::unsigned:imm32:iiiiiiiiiiiiiiii,IIIIIIIIIIIIIIII:(iiiiiiiiiiiiiiii < 16 + IIIIIIIIIIIIIIII) -# start-sanitize-v850e -:cache::unsigned:uimm32:iiiiiiiiiiiiiiii,dddddddddddddddd:((iiiiiiiiiiiiiiii << 16) + dddddddddddddddd) -# end-sanitize-v850e - -:cache::unsigned:vector:iiiii:iiiii - -# start-sanitize-v850e -:cache::unsigned:list12:L,LLLLLLLLLLL:((L << 11) + LLLLLLLLLLL) -:cache::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL) -# end-sanitize-v850e - -:cache::unsigned:bit3:bbb:bbb +:cache:::unsigned:reg1:RRRRR:(RRRRR) +:cache:::unsigned:reg2:rrrrr:(rrrrr) +:cache:::unsigned:reg3:wwwww:(wwwww) +:cache:::unsigned:reg4:W,WWWW:(W + (WWWW << 1)) + +:cache:::unsigned:vreg1:VVVVV:(VVVVV) +:cache:::unsigned:vreg1:VVVV:(VVVV << 1) +:cache:::unsigned:vreg2:vvvvv:(vvvvv) +:cache:::unsigned:vreg2:vvvv:(vvvv << 1) +:cache:::unsigned:vreg3:xxxx:(xxxx << 1) +:cache:::unsigned:vreg3:xxxxx:(xxxxx) +:cache:::unsigned:imm2:ii:(ii) +:cache:::unsigned:imm1:i:(i) + +:cache:::unsigned:reg1e:RRRR:(RRRR << 1) +:cache:::unsigned:reg2e:rrrr:(rrrr << 1) +:cache:::unsigned:reg3e:wwww:(wwww << 1) +:cache:::unsigned:reg4e:mmmm:(mmmm << 1) + +:cache:::unsigned:disp4:dddd:(dddd) +:cache:::unsigned:disp5:dddd:(dddd << 1) +:cache:::unsigned:disp7:ddddddd:ddddddd +:cache:::unsigned:disp8:ddddddd:(ddddddd << 1) +:cache:::unsigned:disp8:dddddd:(dddddd << 2) +:cache:::unsigned:disp9:ddddd,ddd:SEXT32 ((ddddd << 4) + (ddd << 1), 9 - 1) +:cache:::unsigned:disp16:dddddddddddddddd:EXTEND16 (dddddddddddddddd) +:cache:::unsigned:disp16:ddddddddddddddd: EXTEND16 (ddddddddddddddd << 1) +:cache:::unsigned:disp17:d,ddddddddddddddd:SEXT32 (((d <<16) + (ddddddddddddddd << 1)), 17 - 1) +:cache:::unsigned:disp22:dddddd,ddddddddddddddd: SEXT32 ((dddddd << 16) + (ddddddddddddddd << 1), 22 - 1) +:cache:::unsigned:disp23:ddddddd,dddddddddddddddd: SEXT32 ((ddddddd) + (dddddddddddddddd << 7), 23 - 1) +:cache:::unsigned:disp23:dddddd,dddddddddddddddd: SEXT32 ((dddddd << 1) + (dddddddddddddddd << 7), 23 - 1) + +:cache:::unsigned:imm5:iiiii:SEXT32 (iiiii, 4) +:cache:::unsigned:imm6:iiiiii:iiiiii +:cache:::unsigned:imm9:iiiii,IIII:SEXT ((IIII << 5) + iiiii, 9 - 1) +:cache:::unsigned:imm5:iiii:(32 - (iiii << 1)) +:cache:::unsigned:simm16:iiiiiiiiiiiiiiii:EXTEND16 (iiiiiiiiiiiiiiii) +:cache:::unsigned:uimm16:iiiiiiiiiiiiiiii:iiiiiiiiiiiiiiii +:cache:::unsigned:imm32:iiiiiiiiiiiiiiii,IIIIIIIIIIIIIIII:(iiiiiiiiiiiiiiii < 16 + IIIIIIIIIIIIIIII) +:cache:::unsigned:uimm32:iiiiiiiiiiiiiiii,dddddddddddddddd:((iiiiiiiiiiiiiiii << 16) + dddddddddddddddd) + +:cache:::unsigned:vector:iiiii:iiiii + +:cache:::unsigned:list12:L,LLLLLLLLLLL:((L << 11) + LLLLLLLLLLL) +:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL) + +:cache:::unsigned:bit3:bbb:bbb +:cache:::unsigned:bit4:bbbb:bbbb +:cache:::unsigned:bit13:B,BBB:((B << 3) + BBB) // What do we do with an illegal instruction? -:internal:::illegal +:internal::::illegal: { sim_io_eprintf (SD, "Illegal instruction at address 0x%lx\n", (unsigned long) cia); - sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIGILL); + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); } -// Add - +// ADD rrrrr,001110,RRRRR:I:::add "add r, r" { @@ -103,6 +110,21 @@ rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI:::addi +// ADF +rrrrr,111111,RRRRR + wwwww,011101,cccc!13,0:XI:::adf +*v850e2 +*v850e2v3 +*v850e3v5 +"adf %s, r, r, r" +{ + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]); + GR[reg3] = GR[reg1] + GR[reg2] + (cond ? 1 : 0); + TRACE_ALU_RESULT1 (GR[reg3]); +} + + + // AND rrrrr,001010,RRRRR:I:::and "and r, r" @@ -121,115 +143,81 @@ rrrrr,110110,RRRRR + iiiiiiiiiiiiiiii:VI:::andi -// Bcond -// ddddd,1011,ddd,cccc:III:::Bcond -// "b disp9" - -ddddd,1011,ddd,0000:III:::bv -"bv " -{ - COMPAT_1 (OP_580 ()); -} - -ddddd,1011,ddd,0001:III:::bl -"bl " -{ - COMPAT_1 (OP_581 ()); -} - -ddddd,1011,ddd,0010:III:::be -"be " -{ - COMPAT_1 (OP_582 ()); -} - -ddddd,1011,ddd,0011:III:::bnh -"bnh " -{ - COMPAT_1 (OP_583 ()); -} - -ddddd,1011,ddd,0100:III:::bn -"bn " -{ - COMPAT_1 (OP_584 ()); -} - -ddddd,1011,ddd,0101:III:::br -"br " -{ - COMPAT_1 (OP_585 ()); -} - -ddddd,1011,ddd,0110:III:::blt -"blt " +// Map condition code to a string +:%s::::cccc:int cccc { - COMPAT_1 (OP_586 ()); -} + switch (cccc) + { + case 0xf: return "gt"; + case 0xe: return "ge"; + case 0x6: return "lt"; -ddddd,1011,ddd,0111:III:::ble -"ble " -{ - COMPAT_1 (OP_587 ()); -} + case 0x7: return "le"; -ddddd,1011,ddd,1000:III:::bnv -"bnv " -{ - COMPAT_1 (OP_588 ()); -} + case 0xb: return "h"; + case 0x9: return "nl"; + case 0x1: return "l"; -ddddd,1011,ddd,1001:III:::bnl -"bnl " -{ - COMPAT_1 (OP_589 ()); -} + case 0x3: return "nh"; -ddddd,1011,ddd,1010:III:::bne -"bne " -{ - COMPAT_1 (OP_58A ()); -} + case 0x2: return "e"; -ddddd,1011,ddd,1011:III:::bh -"bh " -{ - COMPAT_1 (OP_58B ()); -} + case 0xa: return "ne"; -ddddd,1011,ddd,1100:III:::bp -"bp " -{ - COMPAT_1 (OP_58C ()); + case 0x0: return "v"; + case 0x8: return "nv"; + case 0x4: return "n"; + case 0xc: return "p"; + /* case 0x1: return "c"; */ + /* case 0x9: return "nc"; */ + /* case 0x2: return "z"; */ + /* case 0xa: return "nz"; */ + case 0x5: return "r"; /* always */ + case 0xd: return "sa"; + } + return "(null)"; } -ddddd,1011,ddd,1101:III:::bsa -"bsa " -{ - COMPAT_1 (OP_58D ()); -} -ddddd,1011,ddd,1110:III:::bge -"bge " +// Bcond +ddddd,1011,ddd,cccc:III:::Bcond +"b%s " { - COMPAT_1 (OP_58E ()); + int cond; + if ((ddddd == 0x00) && (ddd == 0x00) && (cccc == 0x05)) { + // Special case - treat "br *" like illegal instruction + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); + } else { + cond = condition_met (cccc); + if (cond) + nia = cia + disp9; + TRACE_BRANCH1 (cond); + } } -ddddd,1011,ddd,1111:III:::bgt -"bgt " +00000111111,d,cccc + ddddddddddddddd,1:VII:::Bcond +"breakpoint":((disp17 == 0) && (cccc == 0x05)) +"b%s " +*v850e2v3 +*v850e3v5 { - COMPAT_1 (OP_58F ()); + int cond; + cond = condition_met (cccc); + if (cond) + nia = cia + disp17; + TRACE_BRANCH_INPUT1 (cond); + TRACE_BRANCH_RESULT (nia); } -// start-sanitize-v850e // BSH rrrrr,11111100000 + wwwww,01101000010:XII:::bsh *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "bsh r, r" { unsigned32 value; @@ -242,23 +230,22 @@ rrrrr,11111100000 + wwwww,01101000010:XII:::bsh GR[reg3] = value; PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); - if (value == 0) PSW |= PSW_Z; + if ((value & 0xffff) == 0) PSW |= PSW_Z; if (value & 0x80000000) PSW |= PSW_S; - if (((value & 0xff) == 0) || (value & 0x00ff) == 0) PSW |= PSW_CY; + if (((value & 0xff) == 0) || ((value & 0xff00) == 0)) PSW |= PSW_CY; TRACE_ALU_RESULT (GR[reg3]); } -// end-sanitize-v850e -// start-sanitize-v850e // BSW rrrrr,11111100000 + wwwww,01101000000:XII:::bsw *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "bsw r, r" { #define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080) @@ -283,14 +270,13 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw -// end-sanitize-v850e -// start-sanitize-v850e // CALLT 0000001000,iiiiii:II:::callt *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "callt " { unsigned32 adr; @@ -305,7 +291,55 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw -// end-sanitize-v850e +// CAXI +rrrrr,111111,RRRRR + wwwww,00011101110:IX:::caxi +*v850e2 +*v850e2v3 +*v850e3v5 +"caxi [reg1], reg2, reg3" +{ + unsigned int z,s,cy,ov; + unsigned32 addr; + unsigned32 token,result; + + addr = GR[reg1]; + + if (mpu_load_mem_test(sd, addr, 4, reg1) + && mpu_store_mem_test(sd, addr, 4, reg1)) + { + token = load_data_mem (sd, addr, 4); + + TRACE_ALU_INPUT2 (token, GR[reg2]); + + result = GR[reg2] - token; + + z = (result == 0); + s = (result & 0x80000000); + cy = (GR[reg2] < token); + ov = ((GR[reg2] & 0x80000000) != (token & 0x80000000) + && (GR[reg2] & 0x80000000) != (result & 0x80000000)); + + if (result == 0) + { + store_data_mem (sd, addr, 4, GR[reg3]); + GR[reg3] = token; + } + else + { + store_data_mem (sd, addr, 4, token); + GR[reg3] = token; + } + + /* Set condition codes. */ + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) + | (cy ? PSW_CY : 0) | (ov ? PSW_OV : 0)); + + TRACE_ALU_RESULT1 (GR[reg3]); + } +} + + // CLR1 10,bbb,111110,RRRRR + dddddddddddddddd:VIII:::clr1 "clr1 , [r]" @@ -313,12 +347,12 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw COMPAT_2 (OP_87C0 ()); } -// start-sanitize-v850e rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "clr1 r, [r]" { COMPAT_2 (OP_E407E0 ()); @@ -326,14 +360,13 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 -// end-sanitize-v850e -// start-sanitize-v850e // CTRET 0000011111100000 + 0000000101000100:X:::ctret *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "ctret" { nia = (CTPC & ~1); @@ -343,34 +376,37 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 -// end-sanitize-v850e -// start-sanitize-v850e // CMOV rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq -"cmov , r, r, r" -{ - COMPAT_2 (OP_32007E0 ()); +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"cmov %s, r, r, r" +{ + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]); + GR[reg3] = cond ? GR[reg1] : GR[reg2]; + TRACE_ALU_RESULT (GR[reg3]); } -// end-sanitize-v850e -// start-sanitize-v850e rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq -"cmov , , r, r" -{ - COMPAT_2 (OP_30007E0 ()); +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"cmov %s, , r, r" +{ + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, imm5, GR[reg2]); + GR[reg3] = cond ? imm5 : GR[reg2]; + TRACE_ALU_RESULT (GR[reg3]); } -// end-sanitize-v850e // CMP rrrrr,001111,RRRRR:I:::cmp "cmp r, r" @@ -395,15 +431,15 @@ rrrrr,010011,iiiii:II:::cmp -// start-sanitize-v850e // DISPOSE // 0000011001,iiiii,L + LLLLLLLLLLL,00000:XIII:::dispose // "dispose , " 0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "dispose , ":RRRRR == 0 "dispose , , [reg1]" { @@ -433,62 +469,153 @@ rrrrr,010011,iiiii:II:::cmp -// end-sanitize-v850e -// start-sanitize-v850e // DIV rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div *v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "div r, r, r" { COMPAT_2 (OP_2C007E0 ()); } - - -// end-sanitize-v850e // DIVH rrrrr!0,000010,RRRRR!0:I:::divh "divh r, r" { - COMPAT_1 (OP_40 ()); + unsigned32 ov, s, z; + signed long int op0, op1, result; + + trace_input ("divh", OP_REG_REG, 0); + + PC = cia; + OP[0] = instruction_0 & 0x1f; + OP[1] = (instruction_0 >> 11) & 0x1f; + + /* Compute the result. */ + op0 = EXTEND16 (State.regs[OP[0]]); + op1 = State.regs[OP[1]]; + + if (op0 == -1 && op1 == 0x80000000) + { + PSW &= ~PSW_Z; + PSW |= PSW_OV | PSW_S; + State.regs[OP[1]] = 0x80000000; + } + else if (op0 == 0) + { + PSW |= PSW_OV; + } + else + { + result = (signed32) op1 / op0; + ov = 0; + + /* Compute the condition codes. */ + z = (result == 0); + s = (result & 0x80000000); + + /* Store the result and condition codes. */ + State.regs[OP[1]] = result; + PSW &= ~(PSW_Z | PSW_S | PSW_OV); + PSW |= ((z ? PSW_Z : 0) | (s ? PSW_S : 0) | (ov ? PSW_OV : 0)); + } + + trace_output (OP_REG_REG); + + PC += 2; + nia = PC; } -// start-sanitize-v850e rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh *v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "divh r, r, r" { COMPAT_2 (OP_28007E0 ()); } - -// end-sanitize-v850e -// start-sanitize-v850e // DIVHU rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu *v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "divhu r, r, r" { COMPAT_2 (OP_28207E0 ()); } - -// end-sanitize-v850e -// start-sanitize-v850e // DIVU rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu *v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "divu r, r, r" { COMPAT_2 (OP_2C207E0 ()); } +// DIVQ +rrrrr,111111,RRRRR + wwwww,01011111100:XI:::divq +*v850e2 +*v850e2v3 +*v850e3v5 +"divq r, r, r" +{ + unsigned int quotient; + unsigned int remainder; + unsigned int divide_by; + unsigned int divide_this; + + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + + divide_by = GR[reg1]; + divide_this = GR[reg2]; + v850_div (sd, divide_by, divide_this, "ient, &remainder); + GR[reg2] = quotient; + GR[reg3] = remainder; + + TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]); +} + + +// DIVQU +rrrrr,111111,RRRRR + wwwww,01011111110:XI:::divqu +*v850e2 +*v850e2v3 +*v850e3v5 +"divq r, r, r" +{ + unsigned int quotient; + unsigned int remainder; + unsigned int divide_by; + unsigned int divide_this; + + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + + divide_by = GR[reg1]; + divide_this = GR[reg2]; + v850_divu (sd, divide_by, divide_this, "ient, &remainder); + GR[reg2] = quotient; + GR[reg3] = remainder; + + TRACE_ALU_RESULT2 (GR[reg2], GR[reg3]); +} + -// end-sanitize-v850e // EI 1000011111100000 + 0000000101100000:X:::ei "ei" @@ -498,6 +625,79 @@ rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu +// EIRET +0000011111100000 + 0000000101001000:X:::eiret +"eiret" +*v850e2 +*v850e2v3 +*v850e3v5 +{ + TRACE_ALU_INPUT1 (MPM & MPM_AUE); + + nia = EIPC; /* next PC */ + if (MPM & MPM_AUE) + { + PSW = EIPSW; + } + else + { + PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP)) + | (EIPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP)); + } + + TRACE_ALU_RESULT1 (PSW); + TRACE_BRANCH_RESULT (nia); +} + + + +// FERET +0000011111100000 + 0000000101001010:X:::feret +"feret" +*v850e2 +*v850e2v3 +*v850e3v5 +{ + TRACE_ALU_INPUT1 (MPM & MPM_AUE); + + nia = FEPC; /* next PC */ + if (MPM & MPM_AUE) + { + PSW = FEPSW; + } + else + { + PSW = (PSW & (PSW_NPV | PSW_DMP | PSW_IMP)) + | (FEPSW & ~(PSW_NPV | PSW_DMP | PSW_IMP)); + } + + TRACE_ALU_RESULT1 (PSW); + TRACE_BRANCH_RESULT (nia); +} + + +// FETRAP +0,bbbb!0,00001000000:I:::fetrap +"fetrap" +*v850e2 +*v850e2v3 +*v850e3v5 +{ + TRACE_ALU_INPUT0 (); + + FEPC = PC + 2; + FEPSW = PSW; + ECR &= ~ECR_FECC; + ECR |= (0x30 + bit4) << 16; + FEIC = 0x30 + bit4; + PSW |= PSW_EP | PSW_ID | PSW_NP; + nia = 0x30; /* next PC */ + + TRACE_ALU_RESULT1 (PSW); + TRACE_BRANCH_RESULT (nia); +} + + // HALT 0000011111100000 + 0000000100100000:X:::halt "halt" @@ -507,13 +707,35 @@ rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu -// start-sanitize-v850e +// HSH +rrrrr,11111100000 + wwwww,01101000110:XII:::hsh +*v850e2 +*v850e2v3 +*v850e3v5 +"hsh r, r" +{ + unsigned32 value; + TRACE_ALU_INPUT1 (GR[reg2]); + + value = 0xffff & GR[reg2]; + GR[reg3] = GR[reg2]; + + PSW &= ~(PSW_Z | PSW_S | PSW_CY | PSW_OV); + + if (value == 0) { PSW |= PSW_Z; PSW |= PSW_CY; } + if (value & 0x80000000) PSW |= PSW_S; + + TRACE_ALU_RESULT1 (GR[reg3]); +} + + // HSW rrrrr,11111100000 + wwwww,01101000100:XII:::hsw *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "hsw r, r" { unsigned32 value; @@ -536,93 +758,476 @@ rrrrr,11111100000 + wwwww,01101000100:XII:::hsw -// end-sanitize-v850e // JARL rrrrr!0,11110,dddddd + ddddddddddddddd,0:V:::jarl "jarl , r" { - COMPAT_2 (OP_780 ()); + GR[reg2] = nia; + nia = cia + disp22; + TRACE_BRANCH1 (GR[reg2]); +} + +00000010111,RRRRR!0 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jarl32 +*v850e2 +*v850e2v3 +*v850e3v5 +"jarl , r" +{ + GR[reg1] = nia; + nia = (cia + imm32) & ~1; + + TRACE_BRANCH_RESULT (nia); } +11000111111,RRRRR + wwwww!0,00101100000:XI:::jarl_reg +*v850e3v5 +"jarl [r], r" +{ + GR[reg3] = nia; + nia = GR[reg1]; + TRACE_BRANCH_RESULT (nia); +} + // JMP 00000000011,RRRRR:I:::jmp "jmp [r]" { - SAVE_1; - trace_input ("jmp", OP_REG, 0); - nia = State.regs[ reg1 ]; - trace_output (OP_REG); + nia = GR[reg1] & ~1; + TRACE_BRANCH0 (); } +00000110111,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jmp32 +*v850e2 +*v850e2v3 +*v850e3v5 +"jmp [r]" +{ + nia = (GR[reg1] + imm32) & ~1; + + TRACE_BRANCH_RESULT (nia); +} // JR 0000011110,dddddd + ddddddddddddddd,0:V:::jr "jr " { - COMPAT_2 (OP_780 ()); + nia = cia + disp22; + TRACE_BRANCH0 (); } +// JR32 +0000001011100000 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jr32 +*v850e2 +*v850e2v3 +*v850e3v5 +"jr " +{ + nia = (cia + imm32) & ~1; + + TRACE_BRANCH_RESULT (nia); +} + // LD rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b -"ld.b [r, r" +"ld.b [r], r" { COMPAT_2 (OP_700 ()); } +00000111100,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.b +"ld.b [r], r" +*v850e2v3 +*v850e3v5 +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = EXTEND8 (load_data_mem (sd, addr, 1)); + GR[reg3] = result; + TRACE_LD (addr, result); +} + rrrrr,111001,RRRRR + ddddddddddddddd,0:VII:::ld.h "ld.h [r], r" { COMPAT_2 (OP_720 ()); } +00000111100,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.h +*v850e2v3 +*v850e3v5 +"ld.h [r], r" +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = EXTEND16 (load_data_mem (sd, addr, 2)); + GR[reg3] = result; + TRACE_LD (addr, result); +} + rrrrr,111001,RRRRR + ddddddddddddddd,1:VII:::ld.w "ld.w [r], r" { COMPAT_2 (OP_10720 ()); } -// start-sanitize-v850e +00000111100,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.w +*v850e2v3 +*v850e3v5 +"ld.w [r], r" +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = load_data_mem (sd, addr, 4); + GR[reg3] = result; + TRACE_LD (addr, result); +} + +00000111101,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.dw +*v850e3v5 +"ld.dw [r], r" +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = load_data_mem (sd, addr, 4); + GR[reg3] = result; + TRACE_LD (addr, result); + result = load_data_mem (sd, addr + 4, 4); + GR[reg3 + 1] = result; + TRACE_LD (addr + 4, result); +} + rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "ld.bu [r], r" { COMPAT_2 (OP_10780 ()); } -// end-sanitize-v850e -// start-sanitize-v850e +00000111101,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.bu +*v850e2v3 +*v850e3v5 +"ld.bu [r], r" +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = load_data_mem (sd, addr, 1); + GR[reg3] = result; + TRACE_LD (addr, result); +} + rrrrr!0,111111,RRRRR + ddddddddddddddd,1:VII:::ld.hu *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "ld.hu [r], r" { COMPAT_2 (OP_107E0 ()); } +00000111101,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.hu +*v850e2v3 +*v850e3v5 +"ld.hu [r], r" +{ + unsigned32 addr = GR[reg1] + disp23; + unsigned32 result = load_data_mem (sd, addr, 2); + GR[reg3] = result; + TRACE_LD (addr, result); +} + + -// end-sanitize-v850e // LDSR -regID,111111,RRRRR + 0000000000100000:IX:::ldsr -"ldsr r, s" +regID,111111,RRRRR + selID,00000100000:IX:::ldsr +"ldsr r, s":(selID == 0) +"ldsr r, s, " { + uint32 sreg = GR[reg1]; TRACE_ALU_INPUT1 (GR[reg1]); - - if (&PSW == &SR[regID]) - PSW = (GR[reg1] & (CPU)->psw_mask); + + /* FIXME: For now we ignore the selID. */ + if (idecode_issue == idecode_v850e3v5_issue && selID != 0) + { + (CPU)->reg.selID_sregs[selID][regID] = sreg; + } + else if (( idecode_issue == idecode_v850e2_issue + || idecode_issue == idecode_v850e3v5_issue + || idecode_issue == idecode_v850e2v3_issue) + && regID < 28) + { + int protect_p = (PSW & PSW_NPV) ? 1 : 0; + + switch (BSEL & 0xffff) + { + case 0x0000: + if ((PSW & PSW_NPV) + && ((regID >= 8 && regID <= 12) + || (regID >= 22 && regID <= 27) + || regID == PSW_REGNO)) + { + protect_p = 0; + } + break; + case 0x1000: /* MPU0 */ + break; + case 0x1001: /* MPU1 */ + break; + case 0x2000: /* FPU */ + if ((PSW & PSW_NPV) + && ((/* regID >= 0 && */ regID <= 5) + || regID == 8 + || regID == 9 + || regID == 10 + || (regID >= 11 && regID <= 26))) + { + protect_p = 0; + } + break; + case 0xff00: + if ((PSW & PSW_NPV) + && (regID == 6 + || regID == 7 + || regID == 8 + || regID == 9 + || regID == 10 + || (regID >= 11 && regID <= 15) + || regID == 18 + || regID == 19 + || (regID >= 21 && regID <= 27))) + { + protect_p = 0; + } + break; + case 0xffff: + if ((PSW & PSW_NPV) + && (regID == 6 + || regID == 7 + || regID == 8 + || regID == 9 + || regID == 10 + || regID == 11 + || regID == 12 + || regID == 15 + || regID == 18 + || regID == 19 + || (regID >= 21 && regID <= 27))) + { + protect_p = 0; + } + break; + } + + if (!protect_p) + { + switch (BSEL & 0xffff) + { + case 0x0000: + case 0xff00: /* user0 bank */ + case 0xffff: /* user1 bank */ + if(regID == PSW_REGNO) + { + SR[regID] = sreg & ((PSW & PSW_NPV) ? 0xf : ~0); + } + else + { + SR[regID] = sreg; + } + break; + case 0x1000: + MPU0_SR[regID] = sreg; + break; + case 0x1001: + if (regID == MPC_REGNO) + { + PPC &= ~PPC_PPE; + SPAL &= ~SPAL_SPE; + IPA0L &= ~IPA_IPE; + IPA1L &= ~IPA_IPE; + IPA2L &= ~IPA_IPE; + IPA3L &= ~IPA_IPE; + DPA0L &= ~DPA_DPE; + DPA1L &= ~DPA_DPE; + DCC &= ~(DCC_DCE0 | DCC_DCE1); + } + else + { + MPU1_SR[regID] = sreg; + } + break; + case 0x2000: /* FPU */ + if (regID == FPST_REGNO) + { + unsigned int val = FPSR & ~(FPSR_PR | FPSR_XC | FPSR_XP); + + val |= ((sreg & FPST_PR) ? FPSR_PR : 0) + | ((sreg & FPST_XCE) ? FPSR_XCE : 0) + | ((sreg & FPST_XCV) ? FPSR_XCV : 0) + | ((sreg & FPST_XCZ) ? FPSR_XCZ : 0) + | ((sreg & FPST_XCO) ? FPSR_XCO : 0) + | ((sreg & FPST_XCU) ? FPSR_XCU : 0) + | ((sreg & FPST_XCI) ? FPSR_XCI : 0) + | ((sreg & FPST_XPV) ? FPSR_XPV : 0) + | ((sreg & FPST_XPZ) ? FPSR_XPZ : 0) + | ((sreg & FPST_XPO) ? FPSR_XPO : 0) + | ((sreg & FPST_XPU) ? FPSR_XPU : 0) + | ((sreg & FPST_XPI) ? FPSR_XPI : 0); + FPSR = val; + } + else if (regID == FPCFG_REGNO) + { + unsigned int val = FPSR & ~(FPSR_RM | FPSR_XE); + + val |= (((sreg & FPCFG_RM) >> 7) << 18) + | ((sreg & FPCFG_XEV) ? FPSR_XEV : 0) + | ((sreg & FPCFG_XEZ) ? FPSR_XEZ : 0) + | ((sreg & FPCFG_XEO) ? FPSR_XEO : 0) + | ((sreg & FPCFG_XEU) ? FPSR_XEU : 0) + | ((sreg & FPCFG_XEI) ? FPSR_XEI : 0); + FPSR = val; + } + + FPU_SR[regID] = sreg; + break; + } + } + } else - SR[regID] = GR[reg1]; + { + SR[regID] = sreg; + } + + TRACE_ALU_RESULT (sreg); +} + + +// MAC +rrrrr,111111,RRRRR + wwww,0011110,mmmm,0:XI:::mac +*v850e2 +*v850e2v3 +*v850e3v5 +"mac r, r, r, r" +{ + unsigned long op0; + unsigned long op1; + unsigned long op2; + unsigned long op2hi; + unsigned long lo; + unsigned long mid1; + unsigned long mid2; + unsigned long hi; + unsigned long RdLo; + unsigned long RdHi; + int carry; + bfd_boolean sign; + + op0 = GR[reg1]; + op1 = GR[reg2]; + op2 = GR[reg3e]; + op2hi = GR[reg3e+1]; + + TRACE_ALU_INPUT4 (op0, op1, op2, op2hi); + + sign = (op0 ^ op1) & 0x80000000; + + if (((signed long) op0) < 0) + op0 = - op0; + + if (((signed long) op1) < 0) + op1 = - op1; + + /* We can split the 32x32 into four 16x16 operations. This ensures + that we do not lose precision on 32bit only hosts: */ + lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF)); + mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF)); + hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking care + to propogate the carries from the additions: */ + RdLo = Add32 (lo, (mid1 << 16), & carry); + RdHi = carry; + RdLo = Add32 (RdLo, (mid2 << 16), & carry); + RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + if (sign) + { + RdLo = ~ RdLo; + RdHi = ~ RdHi; + if (RdLo == 0xFFFFFFFF) + { + RdLo = 0; + RdHi += 1; + } + else + RdLo += 1; + } + + RdLo = Add32 (RdLo, op2, & carry); + RdHi += carry + op2hi; + + /* Store the result and condition codes. */ + GR[reg4e] = RdLo; + GR[reg4e + 1 ] = RdHi; + + TRACE_ALU_RESULT2 (RdLo, RdHi); +} + + + +// MACU +rrrrr,111111,RRRRR + wwww,0011111,mmmm,0:XI:::macu +*v850e2 +*v850e2v3 +*v850e3v5 +"macu r, r, r, r" +{ + unsigned long op0; + unsigned long op1; + unsigned long op2; + unsigned long op2hi; + unsigned long lo; + unsigned long mid1; + unsigned long mid2; + unsigned long hi; + unsigned long RdLo; + unsigned long RdHi; + int carry; - TRACE_ALU_RESULT (SR[regID]); + op0 = GR[reg1]; + op1 = GR[reg2]; + op2 = GR[reg3e]; + op2hi = GR[reg3e + 1]; + + TRACE_ALU_INPUT4 (op0, op1, op2, op2hi); + + /* We can split the 32x32 into four 16x16 operations. This ensures + that we do not lose precision on 32bit only hosts: */ + lo = ( (op0 & 0xFFFF) * (op1 & 0xFFFF)); + mid1 = ( (op0 & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + mid2 = (((op0 >> 16) & 0xFFFF) * (op1 & 0xFFFF)); + hi = (((op0 >> 16) & 0xFFFF) * ((op1 >> 16) & 0xFFFF)); + + /* We now need to add all of these results together, taking care + to propogate the carries from the additions: */ + RdLo = Add32 (lo, (mid1 << 16), & carry); + RdHi = carry; + RdLo = Add32 (RdLo, (mid2 << 16), & carry); + RdHi += (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi); + + RdLo = Add32 (RdLo, op2, & carry); + RdHi += carry + op2hi; + + /* Store the result and condition codes. */ + GR[reg4e] = RdLo; + GR[reg4e+1] = RdHi; + + TRACE_ALU_RESULT2 (RdLo, RdHi); } @@ -631,7 +1236,9 @@ regID,111111,RRRRR + 0000000000100000:IX:::ldsr rrrrr!0,000000,RRRRR:I:::mov "mov r, r" { - COMPAT_1 (OP_0 ()); + TRACE_ALU_INPUT0 (); + GR[reg2] = GR[reg1]; + TRACE_ALU_RESULT (GR[reg2]); } rrrrr!0,010000,iiiii:II:::mov @@ -640,12 +1247,12 @@ rrrrr!0,010000,iiiii:II:::mov COMPAT_1 (OP_200 ()); } -// start-sanitize-v850e 00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "mov , r" { SAVE_2; @@ -656,7 +1263,6 @@ rrrrr!0,010000,iiiii:II:::mov -// end-sanitize-v850e // MOVEA rrrrr!0,110001,RRRRR + iiiiiiiiiiiiiiii:VI:::movea "movea , r, r" @@ -677,33 +1283,30 @@ rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:VI:::movhi -// start-sanitize-v850e // MUL rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "mul r, r, r" { COMPAT_2 (OP_22007E0 ()); } -// end-sanitize-v850e -// start-sanitize-v850e rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "mul , r, r" { COMPAT_2 (OP_24007E0 ()); } - -// end-sanitize-v850e // MULH rrrrr!0,000111,RRRRR:I:::mulh "mulh r, r" @@ -728,13 +1331,13 @@ rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:VI:::mulhi -// start-sanitize-v850e // MULU rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "mulu r, r, r" { COMPAT_2 (OP_22207E0 ()); @@ -742,9 +1345,10 @@ rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "mulu , r, r" { COMPAT_2 (OP_24207E0 ()); @@ -752,12 +1356,11 @@ rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu -// end-sanitize-v850e // NOP 0000000000000000:I:::nop "nop" { - COMPAT_1 (OP_0 ()); + /* do nothing, trace nothing */ } @@ -778,12 +1381,12 @@ rrrrr,000001,RRRRR:I:::not COMPAT_2 (OP_47C0 ()); } -// start-sanitize-v850e rrrrr,111111,RRRRR + 0000000011100010:IX:::not1 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "not1 r, r" { COMPAT_2 (OP_E207E0 ()); @@ -791,7 +1394,6 @@ rrrrr,111111,RRRRR + 0000000011100010:IX:::not1 -// end-sanitize-v850e // OR rrrrr,001000,RRRRR:I:::or "or r, r" @@ -810,13 +1412,13 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori -// start-sanitize-v850e // PREPARE 0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "prepare , " { int i; @@ -841,9 +1443,10 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori 0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "prepare , , sp" { COMPAT_2 (OP_30780 ()); @@ -851,9 +1454,10 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori 0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "prepare , , " { COMPAT_2 (OP_B0780 ()); @@ -861,9 +1465,10 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori 0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "prepare , , " { COMPAT_2 (OP_130780 ()); @@ -871,22 +1476,35 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori 0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "prepare , , " { COMPAT_2 (OP_1B0780 ()); } - - -// end-sanitize-v850e // RETI 0000011111100000 + 0000000101000000:X:::reti "reti" { - COMPAT_2 (OP_14007E0 ()); + if ((PSW & PSW_EP)) + { + nia = (EIPC & ~1); + PSW = EIPSW; + } + else if ((PSW & PSW_NP)) + { + nia = (FEPC & ~1); + PSW = FEPSW; + } + else + { + nia = (EIPC & ~1); + PSW = EIPSW; + } + TRACE_BRANCH1 (PSW); } @@ -904,24 +1522,32 @@ rrrrr,010101,iiiii:II:::sar COMPAT_1 (OP_2A0 ()); } +rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar +*v850e2 +*v850e2v3 +*v850e3v5 +"sar r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_sar(sd, GR[reg1], GR[reg2], &GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} -// start-sanitize-v850e // SASF -rrrrr,1111110,cccc + 0000001000000000:IX:::sasf +rrrrr,1111110,cccc+0000001000000000:IX:::sasf *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq -"sasf , r" +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"sasf %s, r" { COMPAT_2 (OP_20007E0 ()); } - -// end-sanitize-v850e // SATADD rrrrr!0,000110,RRRRR:I:::satadd "satadd r, r" @@ -935,6 +1561,17 @@ rrrrr!0,010001,iiiii:II:::satadd COMPAT_1 (OP_220 ()); } +rrrrr,111111,RRRRR + wwwww,01110111010:XI:::satadd +*v850e2 +*v850e2v3 +*v850e3v5 +"satadd r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_satadd (sd, GR[reg1], GR[reg2], &GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + // SATSUB @@ -944,6 +1581,17 @@ rrrrr!0,000101,RRRRR:I:::satsub COMPAT_1 (OP_A0 ()); } +rrrrr,111111,RRRRR + wwwww,01110011010:XI:::satsub +*v850e2 +*v850e2v3 +*v850e3v5 +"satsub r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_satsub (sd, GR[reg1], GR[reg2], &GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + // SATSUBI @@ -964,42 +1612,276 @@ rrrrr!0,000100,RRRRR:I:::satsubr -// SETF -rrrrr,1111110,cccc + 0000000000000000:IX:::setf -"setf , r" +//SBF +rrrrr,111111,RRRRR + wwwww,011100,cccc!13,0:XI:::sbf +*v850e2 +*v850e2v3 +*v850e3v5 +"sbf %s, r, r, r" { - COMPAT_2 (OP_7E0 ()); + int cond = condition_met (cccc); + TRACE_ALU_INPUT3 (cond, GR[reg1], GR[reg2]); + GR[reg3] = GR[reg2] - GR[reg1] - (cond ? 1 : 0); + TRACE_ALU_RESULT1 (GR[reg3]); } -// SET1 -00,bbb,111110,RRRRR + dddddddddddddddd:VIII:::set1 -"set1 , [r]" -{ - COMPAT_2 (OP_7C0 ()); -} - -// start-sanitize-v850e -rrrrr,111111,RRRRR + 0000000011100000:IX:::set1 -*v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq -"set1 r, [r]" +// SCH0L +rrrrr,11111100000 + wwwww,01101100100:IX:::sch0l +*v850e2 +*v850e2v3 +*v850e3v5 +"sch0l r, r" { - COMPAT_2 (OP_E007E0 ()); -} - + unsigned int pos, op0; + TRACE_ALU_INPUT1 (GR[reg2]); -// end-sanitize-v850e -// SHL -rrrrr,111111,RRRRR + 0000000011000000:IX:::shl -"shl r, r" -{ - COMPAT_2 (OP_C007E0 ()); -} + op0 = GR[reg2]; + + if (op0 == 0xffffffff) + { + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW |= PSW_Z; + pos = 0; + } + else if (op0 == 0xfffffffe) + { + PSW |= PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + pos = 32; + } + else + { + pos = 1; + while (op0 & 0x80000000) + { + op0 <<= 1; + pos++; + } + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + } + + GR[reg3] = pos; + + TRACE_ALU_RESULT1 (GR[reg3]); +} + + + +// SCH0R +rrrrr,11111100000 + wwwww,01101100000:IX:::sch0r +*v850e2 +*v850e2v3 +*v850e3v5 +"sch0r r, r" +{ + unsigned int pos, op0; + + TRACE_ALU_INPUT1 (GR[reg2]); + + op0 = GR[reg2]; + + if (op0 == 0xffffffff) + { + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW |= PSW_Z; + pos = 0; + } + else if (op0 == 0x7fffffff) + { + PSW |= PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + pos = 32; + } + else + { + pos = 1; + while (op0 & 0x00000001) + { + op0 >>= 1; + pos++; + } + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + } + + GR[reg3] = pos; + + TRACE_ALU_RESULT1 (GR[reg3]); +} + +// SCH1L +rrrrr,11111100000 + wwwww,01101100110:IX:::sch1l +*v850e2 +*v850e2v3 +*v850e3v5 +"sch1l r, r" +{ + unsigned int pos, op0; + + TRACE_ALU_INPUT1 (GR[reg2]); + + op0 = GR[reg2]; + + if (op0 == 0x00000000) + { + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW |= PSW_Z; + pos = 0; + } + else if (op0 == 0x00000001) + { + PSW |= PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + pos = 32; + } + else + { + pos = 1; + while (!(op0 & 0x80000000)) + { + op0 <<= 1; + pos++; + } + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + } + + GR[reg3] = pos; + + TRACE_ALU_RESULT1 (GR[reg3]); +} + +// SCH1R +rrrrr,11111100000 + wwwww,01101100010:IX:::sch1r +*v850e2 +*v850e2v3 +*v850e3v5 +"sch1r r, r" +{ + unsigned int pos, op0; + + TRACE_ALU_INPUT1 (GR[reg2]); + + op0 = GR[reg2]; + + if (op0 == 0x00000000) + { + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW |= PSW_Z; + pos = 0; + } + else if (op0 == 0x80000000) + { + PSW |= PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + pos = 32; + } + else + { + pos = 1; + while (!(op0 & 0x00000001)) + { + op0 >>= 1; + pos++; + } + PSW &= ~PSW_CY; + PSW &= ~PSW_OV; + PSW &= ~PSW_S; + PSW &= ~PSW_Z; + } + + GR[reg3] = pos; + + TRACE_ALU_RESULT1 (GR[reg3]); +} + +//SHL +rrrrr,111111,RRRRR + wwwww,00011000010:XI:::shl +*v850e2 +*v850e2v3 +*v850e3v5 +"shl r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_shl(sd, GR[reg1], GR[reg2], &GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + +//SHR +rrrrr,111111,RRRRR + wwwww,00010000010:XI:::shr +*v850e2 +*v850e2v3 +*v850e3v5 +"shr r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_shr(sd, GR[reg1], GR[reg2], &GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + + + +// SETF +rrrrr,1111110,cccc + 0000000000000000:IX:::setf +"setf %s, r" +{ + COMPAT_2 (OP_7E0 ()); +} + + + +// SET1 +00,bbb,111110,RRRRR + dddddddddddddddd:VIII:::set1 +"set1 , [r]" +{ + COMPAT_2 (OP_7C0 ()); +} + +rrrrr,111111,RRRRR + 0000000011100000:IX:::set1 +*v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"set1 r, [r]" +{ + COMPAT_2 (OP_E007E0 ()); +} + + + +// SHL +rrrrr,111111,RRRRR + 0000000011000000:IX:::shl +"shl r, r" +{ + COMPAT_2 (OP_C007E0 ()); +} rrrrr,010110,iiiii:II:::shl "shl , r" @@ -1026,56 +1908,100 @@ rrrrr,010100,iiiii:II:::shr // SLD rrrrr,0110,ddddddd:IV:::sld.b +"sld.bu [ep], r":(PSW & PSW_US) "sld.b [ep], r" { - COMPAT_1 (OP_300 ()); + unsigned32 addr = EP + disp7; + unsigned32 result = load_mem (addr, 1); + if (PSW & PSW_US) + { + GR[reg2] = result; + TRACE_LD_NAME ("sld.bu", addr, result); + } + else + { + result = EXTEND8 (result); + GR[reg2] = result; + TRACE_LD (addr, result); + } } rrrrr,1000,ddddddd:IV:::sld.h +"sld.hu [ep], r":(PSW & PSW_US) "sld.h [ep], r" { - COMPAT_1 (OP_400 ()); + unsigned32 addr = EP + disp8; + unsigned32 result = load_mem (addr, 2); + if (PSW & PSW_US) + { + GR[reg2] = result; + TRACE_LD_NAME ("sld.hu", addr, result); + } + else + { + result = EXTEND16 (result); + GR[reg2] = result; + TRACE_LD (addr, result); + } } rrrrr,1010,dddddd,0:IV:::sld.w "sld.w [ep], r" { - COMPAT_1 (OP_500 ()); + unsigned32 addr = EP + disp8; + unsigned32 result = load_mem (addr, 4); + GR[reg2] = result; + TRACE_LD (addr, result); } -// start-sanitize-v850e rrrrr!0,0000110,dddd:IV:::sld.bu +*v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"sld.b [ep], r":(PSW & PSW_US) "sld.bu [ep], r" { - unsigned long result; - - SAVE_1; - result = load_mem (State.regs[30] + disp4, 1); - - /* start-sanitize-v850eq */ - if (PSW & PSW_US) { - trace_input ("sld.b", OP_LOAD16, 1); - - State.regs[ reg2 ] = EXTEND8 (result); - } else { - /* end-sanitize-v850eq */ - trace_input ("sld.bu", OP_LOAD16, 1); - State.regs[ reg2 ] = result; - /* start-sanitize-v850eq */ - } - /* end-sanitize-v850eq */ - trace_output (OP_LOAD16); + unsigned32 addr = EP + disp4; + unsigned32 result = load_mem (addr, 1); + if (PSW & PSW_US) + { + result = EXTEND8 (result); + GR[reg2] = result; + TRACE_LD_NAME ("sld.b", addr, result); + } + else + { + GR[reg2] = result; + TRACE_LD (addr, result); + } } -// end-sanitize-v850e -// start-sanitize-v850e rrrrr!0,0000111,dddd:IV:::sld.hu +*v850e +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"sld.h [ep], r":(PSW & PSW_US) "sld.hu [ep], r" { - COMPAT_1 (OP_70 ()); + unsigned32 addr = EP + disp5; + unsigned32 result = load_mem (addr, 2); + if (PSW & PSW_US) + { + result = EXTEND16 (result); + GR[reg2] = result; + TRACE_LD_NAME ("sld.h", addr, result); + } + else + { + GR[reg2] = result; + TRACE_LD (addr, result); + } } -// end-sanitize-v850e // SST @@ -1097,8 +2023,6 @@ rrrrr,1010,dddddd,1:IV:::sst.w COMPAT_1 (OP_501 ()); } - - // ST rrrrr,111010,RRRRR + dddddddddddddddd:VII:::st.b "st.b r, [r]" @@ -1106,30 +2030,125 @@ rrrrr,111010,RRRRR + dddddddddddddddd:VII:::st.b COMPAT_2 (OP_740 ()); } +00000111100,RRRRR + wwwww,ddddddd,1101 + dddddddddddddddd:XIV:::st.b +*v850e2v3 +*v850e3v5 +"st.b r, [r]" +{ + unsigned32 addr = GR[reg1] + disp23; + store_data_mem (sd, addr, 1, GR[reg3]); + TRACE_ST (addr, GR[reg3]); +} + rrrrr,111011,RRRRR + ddddddddddddddd,0:VII:::st.h "st.h r, [r]" { COMPAT_2 (OP_760 ()); } +00000111101,RRRRR+wwwww,dddddd,01101+dddddddddddddddd:XIV:::st.h +*v850e2v3 +*v850e3v5 +"st.h r, [r]" +{ + unsigned32 addr = GR[reg1] + disp23; + store_data_mem (sd, addr, 2, GR[reg3]); + TRACE_ST (addr, GR[reg3]); +} + rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w "st.w r, [r]" { COMPAT_2 (OP_10760 ()); } +00000111100,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.w +*v850e2v3 +*v850e3v5 +"st.w r, [r]" +{ + unsigned32 addr = GR[reg1] + disp23; + store_data_mem (sd, addr, 4, GR[reg3]); + TRACE_ST (addr, GR[reg3]); +} + +00000111101,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.dw +*v850e3v5 +"st.dw r, [r]" +{ + unsigned32 addr = GR[reg1] + disp23; + store_data_mem (sd, addr, 4, GR[reg3]); + TRACE_ST (addr, GR[reg3]); + store_data_mem (sd, addr + 4, 4, GR[reg3 + 1]); + TRACE_ST (addr + 4, GR[reg3 + 1]); +} // STSR rrrrr,111111,regID + 0000000001000000:IX:::stsr "stsr s, r" { - TRACE_ALU_INPUT1 (SR[regID]); - GR[reg2] = SR[regID]; - TRACE_ALU_RESULT (GR[reg2]); -} + uint32 sreg = 0; + if ((idecode_issue == idecode_v850e2_issue + || idecode_issue == idecode_v850e3v5_issue + || idecode_issue == idecode_v850e2v3_issue) + && regID < 28) + { + switch (BSEL & 0xffff) + { + case 0x0000: + case 0xff00: /* USER 0 */ + case 0xffff: /* USER 1 */ + sreg = SR[regID]; + break; + case 0x1000: + sreg = MPU0_SR[regID]; + break; + case 0x1001: + sreg = MPU1_SR[regID]; + break; + case 0x2000: + if (regID == FPST_REGNO) + { + sreg = ((FPSR & FPSR_PR) ? FPST_PR : 0) + | ((FPSR & FPSR_XCE) ? FPST_XCE : 0) + | ((FPSR & FPSR_XCV) ? FPST_XCV : 0) + | ((FPSR & FPSR_XCZ) ? FPST_XCZ : 0) + | ((FPSR & FPSR_XCO) ? FPST_XCO : 0) + | ((FPSR & FPSR_XCU) ? FPST_XCU : 0) + | ((FPSR & FPSR_XCI) ? FPST_XCI : 0) + | ((FPSR & FPSR_XPV) ? FPST_XPV : 0) + | ((FPSR & FPSR_XPZ) ? FPST_XPZ : 0) + | ((FPSR & FPSR_XPO) ? FPST_XPO : 0) + | ((FPSR & FPSR_XPU) ? FPST_XPU : 0) + | ((FPSR & FPSR_XPI) ? FPST_XPI : 0); + } + else if (regID == FPCFG_REGNO) + { + sreg = (((FPSR & FPSR_RM) >> 18) << 7) + | ((FPSR & FPSR_XEV) ? FPCFG_XEV : 0) + | ((FPSR & FPSR_XEZ) ? FPCFG_XEZ : 0) + | ((FPSR & FPSR_XEO) ? FPCFG_XEO : 0) + | ((FPSR & FPSR_XEU) ? FPCFG_XEU : 0) + | ((FPSR & FPSR_XEI) ? FPCFG_XEI : 0); + } + else + { + sreg = FPU_SR[regID]; + } + break; + } + } + else + { + sreg = SR[regID]; + } + TRACE_ALU_INPUT1 (sreg); + GR[reg2] = sreg; + TRACE_ALU_RESULT (GR[reg2]); +} // SUB rrrrr,001101,RRRRR:I:::sub @@ -1138,8 +2157,6 @@ rrrrr,001101,RRRRR:I:::sub COMPAT_1 (OP_1A0 ()); } - - // SUBR rrrrr,001100,RRRRR:I:::subr "subr r, r" @@ -1147,15 +2164,13 @@ rrrrr,001100,RRRRR:I:::subr COMPAT_1 (OP_180 ()); } - - -// start-sanitize-v850e // SWITCH 00000000010,RRRRR:I:::switch *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "switch r" { unsigned long adr; @@ -1166,16 +2181,13 @@ rrrrr,001100,RRRRR:I:::subr trace_output (OP_REG); } - - -// end-sanitize-v850e -// start-sanitize-v850e // SXB 00000000101,RRRRR:I:::sxb *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "sxb r" { TRACE_ALU_INPUT1 (GR[reg1]); @@ -1183,16 +2195,13 @@ rrrrr,001100,RRRRR:I:::subr TRACE_ALU_RESULT (GR[reg1]); } - - -// end-sanitize-v850e -// start-sanitize-v850e // SXH 00000000111,RRRRR:I:::sxh *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "sxh r" { TRACE_ALU_INPUT1 (GR[reg1]); @@ -1200,9 +2209,6 @@ rrrrr,001100,RRRRR:I:::subr TRACE_ALU_RESULT (GR[reg1]); } - - -// end-sanitize-v850e // TRAP 00000111111,iiiii + 0000000100000000:X:::trap "trap " @@ -1210,8 +2216,6 @@ rrrrr,001100,RRRRR:I:::subr COMPAT_2 (OP_10007E0 ()); } - - // TST rrrrr,001011,RRRRR:I:::tst "tst r, r" @@ -1219,8 +2223,6 @@ rrrrr,001011,RRRRR:I:::tst COMPAT_1 (OP_160 ()); } - - // TST1 11,bbb,111110,RRRRR + dddddddddddddddd:VIII:::tst1 "tst1 , [r]" @@ -1228,20 +2230,17 @@ rrrrr,001011,RRRRR:I:::tst COMPAT_2 (OP_C7C0 ()); } -// start-sanitize-v850e rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1 *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "tst1 r, [r]" { COMPAT_2 (OP_E607E0 ()); } - - -// end-sanitize-v850e // XOR rrrrr,001001,RRRRR:I:::xor "xor r, r" @@ -1249,8 +2248,6 @@ rrrrr,001001,RRRRR:I:::xor COMPAT_1 (OP_120 ()); } - - // XORI rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori "xori , r, r" @@ -1258,15 +2255,13 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori COMPAT_2 (OP_6A0 ()); } - - -// start-sanitize-v850e // ZXB 00000000100,RRRRR:I:::zxb *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "zxb r" { TRACE_ALU_INPUT1 (GR[reg1]); @@ -1274,16 +2269,13 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori TRACE_ALU_RESULT (GR[reg1]); } - - -// end-sanitize-v850e -// start-sanitize-v850e // ZXH 00000000110,RRRRR:I:::zxh *v850e -// start-sanitize-v850eq -*v850eq -// end-sanitize-v850eq +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 "zxh r" { TRACE_ALU_INPUT1 (GR[reg1]); @@ -1291,279 +2283,2060 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori TRACE_ALU_RESULT (GR[reg1]); } +// Right field must be zero so that it doesn't clash with DIVH +// Left field must be non-zero so that it doesn't clash with SWITCH +11111,000010,00000:I:::break +*v850 +*v850e +{ + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); +} +11111,000010,00000:I:::dbtrap +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"dbtrap" +{ + if (STATE_OPEN_KIND (SD) == SIM_OPEN_DEBUG) + { + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); + } + else + { + DBPC = cia + 2; + DBPSW = PSW; + PSW = PSW | (PSW_NP | PSW_EP | PSW_ID); + PC = 0x00000060; + nia = 0x00000060; + TRACE_BRANCH0 (); + } +} -// end-sanitize-v850e -// Special - breakpoint - illegal -// Hopefully, in the future, this instruction will go away -1111111111111111 + 1111111111111111:Z:::breakpoint -*v850 +// New breakpoint: 0x7E0 0x7E0 +00000,111111,00000 + 00000,11111,100000:X:::ilgop { - sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIGTRAP); + sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGTRAP); } -// start-sanitize-v850e -// First field could be any nonzero value. -11111,000010,00000:I:::break +// Return from debug trap: 0x146007e0 +0000011111100000 + 0000000101000110:X:::dbret +*v850e1 +*v850e2 +*v850e2v3 +*v850e3v5 +"dbret" { - sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIGTRAP); + nia = DBPC; + PSW = DBPSW; + TRACE_BRANCH1 (PSW); } -// end-sanitize-v850e +// +// FLOAT +// -// start-sanitize-v850eq -// DIVHN -rrrrr,111111,RRRRR + wwwww,01010,iiii,00:XI:::divhn -*v850eq -"divhn , r, r, r" +// Map condition code to a string +:%s::::FFFF:int FFFF { - signed32 quotient; - signed32 remainder; - signed32 divide_by; - signed32 divide_this; - boolean overflow = false; - SAVE_2; - - trace_input ("divhn", OP_IMM_REG_REG_REG, 0); - - divide_by = EXTEND16 (State.regs[ reg1 ]); - divide_this = State.regs[ reg2 ]; - - divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); - - State.regs[ reg2 ] = quotient; - State.regs[ reg3 ] = remainder; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); - - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient < 0) PSW |= PSW_S; - - trace_output (OP_IMM_REG_REG_REG); + switch (FFFF) + { + case 0: return "f"; + case 1: return "un"; + case 2: return "eq"; + case 3: return "ueq"; + case 4: return "olt"; + case 5: return "ult"; + case 6: return "ole"; + case 7: return "ule"; + case 8: return "sf"; + case 9: return "ngle"; + case 10: return "seq"; + case 11: return "ngl"; + case 12: return "lt"; + case 13: return "nge"; + case 14: return "le"; + case 15: return "ngt"; + } + return "(null)"; } +// ABSF.D +rrrr,011111100000 + wwww,010001011000:F_I:::absf_d +*v850e2v3 +*v850e3v5 +"absf.d r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); -// DIVHUN -rrrrr,111111,RRRRR + wwwww,01010,iiii,10:XI:::divhun -*v850eq -"divhun , r, r, r" -{ - signed32 quotient; - signed32 remainder; - signed32 divide_by; - signed32 divide_this; - boolean overflow = false; - SAVE_2; - - trace_input ("divhun", OP_IMM_REG_REG_REG, 0); - - divide_by = State.regs[ reg1 ] & 0xffff; - divide_this = State.regs[ reg2 ]; - - divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); - - State.regs[ reg2 ] = quotient; - State.regs[ reg3 ] = remainder; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); - - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient & 0x80000000) PSW |= PSW_S; + status = sim_fpu_abs (&ans, &wop); + check_invalid_snan(sd, status, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); - trace_output (OP_IMM_REG_REG_REG); + TRACE_FP_RESULT_FPU1 (&ans); } +// ABSF.S +rrrrr,11111100000 + wwwww,10001001000:F_I:::absf_s +*v850e2v3 +*v850e3v5 +"absf.s r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + status = sim_fpu_abs (&ans, &wop); + check_invalid_snan(sd, status, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} -// DIVN -rrrrr,111111,RRRRR + wwwww,01011,iiii,00:XI:::divn -*v850eq -"divn , r, r, r" +// ADDF.D +rrrr,0111111,RRRR,0 + wwww,010001110000:F_I:::addf_d +*v850e2v3 +*v850e3v5 +"addf.d r, r, r" { - signed32 quotient; - signed32 remainder; - signed32 divide_by; - signed32 divide_this; - boolean overflow = false; - SAVE_2; - - trace_input ("divn", OP_IMM_REG_REG_REG, 0); + sim_fpu ans, wop1, wop2; + sim_fpu_status status; - divide_by = State.regs[ reg1 ]; - divide_this = State.regs[ reg2 ]; + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); - divn (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); - - State.regs[ reg2 ] = quotient; - State.regs[ reg3 ] = remainder; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); - - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient < 0) PSW |= PSW_S; - - trace_output (OP_IMM_REG_REG_REG); -} + status = sim_fpu_add (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} -// DIVUN -rrrrr,111111,RRRRR + wwwww,01011,iiii,10:XI:::divun -*v850eq -"divun , r, r, r" +// ADDF.S +rrrrr,111111,RRRRR + wwwww,10001100000:F_I:::addf_s +*v850e2v3 +*v850e3v5 +"addf.s r, r, r" { - signed32 quotient; - signed32 remainder; - signed32 divide_by; - signed32 divide_this; - boolean overflow = false; - SAVE_2; + sim_fpu ans, wop1, wop2; + sim_fpu_status status; - trace_input ("divun", OP_IMM_REG_REG_REG, 0); + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); - divide_by = State.regs[ reg1 ]; - divide_this = State.regs[ reg2 ]; + status = sim_fpu_add (&ans, &wop1, &wop2); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); - divun (imm5, divide_by, divide_this, & quotient, & remainder, & overflow); - - State.regs[ reg2 ] = quotient; - State.regs[ reg3 ] = remainder; - - /* Set condition codes. */ - PSW &= ~(PSW_Z | PSW_S | PSW_OV); - - if (overflow) PSW |= PSW_OV; - if (quotient == 0) PSW |= PSW_Z; - if (quotient & 0x80000000) PSW |= PSW_S; + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); - trace_output (OP_IMM_REG_REG_REG); + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); } +// CMOVF.D +rrrr,0111111,RRRR,0 + wwww!0,01000001,bbb,0:F_I:::cmovf_d +*v850e2v3 +*v850e3v5 +"cmovf.d , r, r, r" +{ + unsigned int ophi,oplow; + sim_fpu ans, wop1, wop2; + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2); -// SDIVHN -rrrrr,111111,RRRRR + wwwww,00110,iiii,00:XI:::sdivhn -*v850eq -"sdivhn , r, r, r" -{ - COMPAT_2 (OP_18007E0 ()); + if (TEST_FPCC(bbb)) + { + ophi = GR[reg1e+1]; + oplow = GR[reg1e]; + ans = wop1; + } + else + { + ophi = GR[reg2e+1]; + oplow = GR[reg2e]; + ans = wop2; + } + + GR[reg3e+1] = ophi; + GR[reg3e] = oplow; + TRACE_FP_RESULT_FPU1 (&ans);; } +// CMOVF.S +rrrrr,111111,RRRRR!0 + wwwww!0,1000000,bbb,0:F_I:::cmovf_s +*v850e2v3 +*v850e3v5 +"cmovf.d , r, r, r" +{ + unsigned int op; + sim_fpu ans, wop1, wop2; + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_BOOL1_FPU2 (TEST_FPCC(bbb), &wop1, &wop2); -// SDIVHUN -rrrrr,111111,RRRRR + wwwww,00110,iiii,10:XI:::sdivhun -*v850eq -"sdivhun , r, r, r" -{ - COMPAT_2 (OP_18207E0 ()); + if (TEST_FPCC(bbb)) + { + op = GR[reg1]; + ans = wop1; + } + else + { + op = GR[reg2]; + ans = wop2; + } + + GR[reg3] = op; + TRACE_FP_RESULT_FPU1 (&ans); } +// CMPF.D +rrrr,0111111,RRRR,0 + 0,FFFF,1000011,bbb,0:F_I:::cmpf_d +*v850e2v3 +*v850e3v5 +"cmpf.d %s, r, r":(bbb == 0) +"cmpf.d %s, r, r, " +{ + int result; + sim_fpu wop1; + sim_fpu wop2; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop2, &wop1); + + result = v850_float_compare(sd, FFFF, wop2, wop1, 1); + if (result) + SET_FPCC(bbb); + else + CLEAR_FPCC(bbb); -// SDIVN -rrrrr,111111,RRRRR + wwwww,00111,iiii,00:XI:::sdivn -*v850eq -"sdivn , r, r, r" -{ - COMPAT_2 (OP_1C007E0 ()); + TRACE_FP_RESULT_BOOL (result); } +// CMPF.S +rrrrr,111111,RRRRR + 0,FFFF,1000010,bbb,0:F_I:::cmpf_s +*v850e2v3 +*v850e3v5 +"cmpf.s %s, r, r":(bbb == 0) +"cmpf.s %s, r, r, " +{ + int result; + sim_fpu wop1; + sim_fpu wop2; + sim_fpu_32to( &wop1, GR[reg1] ); + sim_fpu_32to( &wop2, GR[reg2] ); + TRACE_FP_INPUT_FPU2 (&wop2, &wop1); -// SDIVUN -rrrrr,111111,RRRRR + wwwww,00111,iiii,10:XI:::sdivun -*v850eq -"sdivun , r, r, r" -{ - COMPAT_2 (OP_1C207E0 ()); -} + result = v850_float_compare(sd, FFFF, wop2, wop1, 0); + if (result) + SET_FPCC(bbb); + else + CLEAR_FPCC(bbb); + TRACE_FP_RESULT_BOOL (result); +} -// PUSHML -000001111110,LLLL + LLLLLLLLLLLL,S,001:XIV:::pushml -*v850eq -"pushml " +// CVTF.DL +rrrr,011111100100 + wwww,010001010100:F_I:::cvtf_dl +*v850e2v3 +*v850e3v5 +"cvtf.dl r, r" { - int i; - SAVE_2; - - trace_input ("pushml", OP_PUSHPOP3, 0); + signed64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND()); + + check_cvt_fi(sd, status, 1); + + GR[reg3e] = ans; + GR[reg3e+1] = ans>>32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// CVTF.DS +rrrr,011111100011 + wwwww,10001010010:F_I:::cvtf_ds +*v850e2v3 +*v850e3v5 +"cvtf.ds r, r" +{ + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + check_cvt_fi(sd, status, 0); + + sim_fpu_to32 (&GR[reg3], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// CVTF.DW +rrrr,011111100100 + wwwww,10001010000:F_I:::cvtf_dw +*v850e2v3 +*v850e3v5 +"cvtf.dw r, r" +{ + int32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + status |= sim_fpu_to32i (&ans, &wop, FPSR_GET_ROUND()); + + check_cvt_fi(sd, status, 1); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// CVTF.LD +rrrr,011111100001 + wwww,010001010010:F_I:::cvtf_ld +*v850e2v3 +*v850e3v5 +"cvtf.ld r, r" +{ + signed64 op; + sim_fpu wop; + sim_fpu_status status; + + op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e]; + TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]); + + sim_fpu_i64to (&wop, op, FPSR_GET_ROUND()); + status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + + check_cvt_if(sd, status, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// CVTF.LS +rrrr,011111100001 + wwwww,10001000010:F_I:::cvtf_ls +*v850e2v3 +*v850e3v5 +"cvtf.ls r, r" +{ + signed64 op; + sim_fpu wop; + sim_fpu_status status; + + op = ((signed64)GR[reg2e+1] << 32L) | GR[reg2e]; + TRACE_FP_INPUT_WORD2 (GR[reg2e], GR[reg2e+1]); + + sim_fpu_i64to (&wop, op, FPSR_GET_ROUND()); + status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + + check_cvt_if(sd, status, 0); + + sim_fpu_to32 (&GR[reg3], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// CVTF.SD +rrrrr,11111100010 + wwww,010001010010:F_I:::cvtf_sd +*v850e2v3 +*v850e3v5 +"cvtf.sd r, r" +{ + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + check_cvt_ff(sd, status, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// CVTF.SL +rrrrr,11111100100 + wwww,010001000100:F_I:::cvtf_sl +*v850e2v3 +*v850e3v5 +"cvtf.sl r, r" +{ + signed64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + status |= sim_fpu_to64i (&ans, &wop, FPSR_GET_ROUND()); + + check_cvt_fi(sd, status, 0); + + GR[reg3e] = ans; + GR[reg3e+1] = ans >> 32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// CVTF.SW +rrrrr,11111100100 + wwwww,10001000000:F_I:::cvtf_sw +*v850e2v3 +*v850e3v5 +"cvtf.sw r, r" +{ + int32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + status |= sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 0); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// CVTF.WD +rrrrr,11111100000 + wwww,010001010010:F_I:::cvtf_wd +*v850e2v3 +*v850e3v5 +"cvtf.wd r, r" +{ + sim_fpu wop; + sim_fpu_status status; + + TRACE_FP_INPUT_WORD1 (GR[reg2]); + sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND()); + status = sim_fpu_round_64 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + + check_cvt_if(sd, status, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// CVTF.WS +rrrrr,11111100000 + wwwww,10001000010:F_I:::cvtf_ws +*v850e2v3 +*v850e3v5 +"cvtf.ws r, r" +{ + sim_fpu wop; + sim_fpu_status status; + + TRACE_FP_INPUT_WORD1 (GR[reg2]); + sim_fpu_i32to (&wop, GR[reg2], FPSR_GET_ROUND()); + status = sim_fpu_round_32 (&wop, FPSR_GET_ROUND(), sim_fpu_denorm_zero); + + check_cvt_if(sd, status, 0); + + sim_fpu_to32 (&GR[reg3], &wop); + TRACE_FP_RESULT_FPU1 (&wop); +} + +// DIVF.D +rrrr,0111111,RRRR,0 + wwww,010001111110:F_I:::divf_d +*v850e2v3 +*v850e3v5 +"divf.d r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_div (&ans, &wop2, &wop1); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// DIVF.S +rrrrr,111111,RRRRR + wwwww,10001101110:F_I:::divf_s +*v850e2v3 +*v850e3v5 +"divf.s r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_div (&ans, &wop2, &wop1); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MADDF.S +rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s +*v850e2v3 +"maddf.s r, r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + wop1 = ans; + status |= sim_fpu_add (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg4], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// FMAF.S +rrrrr,111111,RRRRR + wwwww,10011100000:F_I:::fmaf_s +*v850e3v5 +"fmaf.s r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + wop1 = ans; + status |= sim_fpu_add (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MAXF.D +rrrr,0111111,RRRR,0 + wwww,010001111000:F_I:::maxf_d +*v850e2v3 +*v850e3v5 +"maxf.d r, r, r" +{ + sim_fpu ans, wop1, wop2; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2)) + { + if (FPSR & FPSR_XEV) + { + SignalExceptionFPE(sd, 1); + } + else + { + ans = sim_fpu_qnan; + } + } + else if (FPSR & FPSR_FS + && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1)) + && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2)))) + { + ans = sim_fpu_zero; + } + else + { + sim_fpu_max (&ans, &wop1, &wop2); + } - /* Store the registers with lower number registers being placed at - higher addresses. */ + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} - for (i = 0; i < 15; i++) - if ((OP[3] & (1 << type3_regs[ i ]))) - { - SP -= 4; - store_mem (SP & ~ 3, 4, State.regs[ i + 1 ]); - } +// MAXF.S +rrrrr,111111,RRRRR + wwwww,10001101000:F_I:::maxf_s +*v850e2v3 +*v850e3v5 +"maxf.s r, r, r" +{ + sim_fpu ans, wop1, wop2; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2)) + { + if (FPSR & FPSR_XEV) + { + SignalExceptionFPE(sd, 0); + } + else + { + ans = sim_fpu_qnan; + } + } + else if ((FPSR & FPSR_FS) + && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1)) + && (sim_fpu_is_zero (&wop2)|| sim_fpu_is_denorm (&wop2)))) + { + ans = sim_fpu_zero; + } + else + { + sim_fpu_max (&ans, &wop1, &wop2); + } - if (OP[3] & (1 << 3)) + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MINF.D +rrrr,0111111,RRRR,0 + wwww,010001111010:F_I:::minf_d +*v850e2v3 +*v850e3v5 +"minf.d r, r, r" +{ + sim_fpu ans, wop1, wop2; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2)) { - SP -= 4; - - store_mem (SP & ~ 3, 4, PSW); + if (FPSR & FPSR_XEV) + { + SignalExceptionFPE(sd, 1); + } + else + { + ans = sim_fpu_qnan; + } + } + else if (FPSR & FPSR_FS + && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1)) + && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2)))) + { + ans = sim_fpu_zero; + } + else + { + sim_fpu_min (&ans, &wop1, &wop2); } - if (OP[3] & (1 << 19)) + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MINF.S +rrrrr,111111,RRRRR + wwwww,10001101010:F_I:::minf_s +*v850e2v3 +*v850e3v5 +"minf.s r, r, r" +{ + sim_fpu ans, wop1, wop2; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + if (sim_fpu_is_nan(&wop1) || sim_fpu_is_nan(&wop2)) { - SP -= 8; - - if ((PSW & PSW_NP) && ((PSW & PSW_EP) == 0)) + if (FPSR & FPSR_XEV) { - store_mem ((SP + 4) & ~ 3, 4, FEPC); - store_mem ( SP & ~ 3, 4, FEPSW); + SignalExceptionFPE(sd, 0); } else { - store_mem ((SP + 4) & ~ 3, 4, EIPC); - store_mem ( SP & ~ 3, 4, EIPSW); + ans = sim_fpu_qnan; } } + else if (FPSR & FPSR_FS + && ((sim_fpu_is_zero (&wop1) || sim_fpu_is_denorm (&wop1)) + && (sim_fpu_is_zero (&wop2) || sim_fpu_is_denorm (&wop2)))) + { + ans = sim_fpu_zero; + } + else + { + sim_fpu_min (&ans, &wop1, &wop2); + } - trace_output (OP_PUSHPOP2); + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MSUBF.S +rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s +*v850e2v3 +"msubf.s r, r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_sub (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg4], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// FMSF.S +rrrrr,111111,RRRRR + wwwww,10011100010:F_I:::fmsf_s +*v850e3v5 +"fmsf.s r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_sub (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MULF.D +rrrr,0111111,RRRR,0 + wwww,010001110100:F_I:::mulf_d +*v850e2v3 +*v850e3v5 +"mulf.d r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// MULF.S +rrrrr,111111,RRRRR + wwwww,10001100100:F_I:::mulf_s +*v850e2v3 +*v850e3v5 +"mulf.s r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// NEGF.D +rrrr,011111100001 + wwww,010001011000:F_I:::negf_d +*v850e2v3 +*v850e3v5 +"negf.d r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_neg (&ans, &wop); + + check_invalid_snan(sd, status, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// NEGF.S +rrrrr,11111100001 + wwwww,10001001000:F_I:::negf_s +*v850e2v3 +*v850e3v5 +"negf.s r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_neg (&ans, &wop); + + check_invalid_snan(sd, status, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// NMADDF.S +rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s +*v850e2v3 +"nmaddf.s r, r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + wop1 = ans; + status |= sim_fpu_add (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_neg (&ans, &wop1); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg4], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// FNMAF.S +rrrrr,111111,RRRRR + wwwww,10011100100:F_I:::fnmaf_s +*v850e3v5 +"fnmaf.s r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + wop1 = ans; + status |= sim_fpu_add (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_neg (&ans, &wop1); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); } +// NMSUBF.S +rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s +*v850e2v3 +"nmsubf.s r, r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_sub (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_neg (&ans, &wop1); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg4], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// FNMSF.S +rrrrr,111111,RRRRR + wwwww,10011100110:F_I:::fnmsf_s +*v850e3v5 +"fnmsf.s r, r, r" +{ + sim_fpu ans, wop1, wop2, wop3; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + sim_fpu_32to (&wop3, GR[reg3]); + TRACE_FP_INPUT_FPU3 (&wop1, &wop2, &wop3); + + status = sim_fpu_mul (&ans, &wop1, &wop2); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_sub (&ans, &wop1, &wop3); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop1 = ans; + status |= sim_fpu_neg (&ans, &wop1); + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} -// PUSHHML -000001111110,LLLL + LLLLLLLLLLLL,S,011:XIV:::pushmh -*v850eq -"pushhml " +// RECIPF.D +rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d +*v850e2v3 +*v850e3v5 +"recipf.d r, r" { - COMPAT_2 (OP_307E0 ()); + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_div (&ans, &sim_fpu_one, &wop); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); } +// RECIPF.S +rrrrr,11111100001 + wwwww,10001001110:F_I:::recipf.s +*v850e2v3 +*v850e3v5 +"recipf.s r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_div (&ans, &sim_fpu_one, &wop); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} -// POPML -000001111111,LLLL + LLLLLLLLLLLL,S,001:XIV:::popml -*v850eq -"popml " +// RSQRTF.D +rrrr,011111100010 + wwww,010001011110:F_I:::rsqrtf.d +*v850e2v3 +*v850e3v5 +"rsqrtf.d r, r" { - COMPAT_2 (OP_107F0 ()); + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_sqrt (&ans, &wop); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop = ans; + status = sim_fpu_div (&ans, &sim_fpu_one, &wop); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); } +// RSQRTF.S +rrrrr,11111100010 + wwwww,10001001110:F_I:::rsqrtf.s +*v850e2v3 +*v850e3v5 +"rsqrtf.s r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_sqrt (&ans, &wop); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + wop = ans; + status = sim_fpu_div (&ans, &sim_fpu_one, &wop); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + update_fpsr (sd, status, FPSR_XEV | FPSR_XEZ | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); -// POPMH -000001111111,LLLL + LLLLLLLLLLLL,S,011:XIV:::popmh -*v850eq -"popmh " + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// SQRTF.D +rrrr,011111100000 + wwww,010001011110:F_I:::sqrtf.d +*v850e2v3 +*v850e3v5 +"sqrtf.d r, r" { - COMPAT_2 (OP_307F0 ()); + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_sqrt (&ans, &wop); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); } +// SQRTF.S +rrrrr,11111100000 + wwwww,10001001110:F_I:::sqrtf.s +*v850e2v3 +*v850e3v5 +"sqrtf.s r, r" +{ + sim_fpu ans, wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_sqrt (&ans, &wop); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} -// end-sanitize-v850eq +// SUBF.D +rrrr,0111111,RRRR,0 + wwww,010001110010:F_I:::subf.d +*v850e2v3 +*v850e3v5 +"subf.d r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_232to (&wop1, GR[reg1e+1], GR[reg1e]); + sim_fpu_232to (&wop2, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_sub (&ans, &wop2, &wop1); + status |= sim_fpu_round_64 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 1); + + sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// SUBF.S +rrrrr,111111,RRRRR + wwwww,10001100010:F_I:::subf.s +*v850e2v3 +*v850e3v5 +"subf.s r, r, r" +{ + sim_fpu ans, wop1, wop2; + sim_fpu_status status; + + sim_fpu_32to (&wop1, GR[reg1]); + sim_fpu_32to (&wop2, GR[reg2]); + TRACE_FP_INPUT_FPU2 (&wop1, &wop2); + + status = sim_fpu_sub (&ans, &wop2, &wop1); + status |= sim_fpu_round_32 (&ans, FPSR_GET_ROUND(), sim_fpu_denorm_underflow_inexact); + + update_fpsr (sd, status, FPSR_XEV | FPSR_XEI | FPSR_XEO | FPSR_XEU, 0); + + sim_fpu_to32 (&GR[reg3], &ans); + TRACE_FP_RESULT_FPU1 (&ans); +} + +// TRFSR +0000011111100000 + 000001000000,bbb,0:F_I:::trfsr +*v850e2v3 +*v850e3v5 +"trfsr":(bbb == 0) +"trfsr " +{ + TRACE_ALU_INPUT1 (GET_FPCC()); + + if (TEST_FPCC (bbb)) + PSW |= PSW_Z; + else + PSW &= ~PSW_Z; + + TRACE_ALU_RESULT1 (PSW); +} + +// TRNCF.DL +rrrr,011111100001 + wwww,010001010100:F_I:::trncf_dl +*v850e2v3 +*v850e3v5 +"trncf.dl r, r" +{ + signed64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 1); + + GR[reg3e] = ans; + GR[reg3e+1] = ans>>32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// TRNCF.DUL +rrrr,011111110001 + wwww,010001010100:F_I:::trncf_dul +*v850e2v3 +*v850e3v5 +"trncf.dul r, r" +{ + unsigned64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to64u (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 1); + + GR[reg3e] = ans; + GR[reg3e+1] = ans>>32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// TRNCF.DW +rrrr,011111100001 + wwwww,10001010000:F_I:::trncf_dw +*v850e2v3 +*v850e3v5 +"trncf.dw r, r" +{ + int32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 1); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// TRNCF.DUW +rrrr,011111110001 + wwwww,10001010000:F_I:::trncf_duw +*v850e2v3 +*v850e3v5 +"trncf.duw r, r" +{ + uint32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_232to (&wop, GR[reg2e+1], GR[reg2e]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to32u (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 1); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// TRNCF.SL +rrrrr,11111100001 + wwww,010001000100:F_I:::trncf_sl +*v850e2v3 +*v850e3v5 +"trncf.sl r, r" +{ + signed64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to64i (&ans, &wop, sim_fpu_round_zero); + + GR[reg3e] = ans; + GR[reg3e+1] = ans >> 32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// TRNCF.SUL +rrrrr,11111110001 + wwww,010001000100:F_I:::trncf_sul +*v850e2v3 +*v850e3v5 +"trncf.sul r, r" +{ + unsigned64 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to64u (&ans, &wop, sim_fpu_round_zero); + + GR[reg3e] = ans; + GR[reg3e+1] = ans >> 32L; + TRACE_FP_RESULT_WORD2 (GR[reg3e], GR[reg3e+1]); +} + +// TRNCF.SW +rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw +*v850e2v3 +*v850e3v5 +"trncf.sw r, r" +{ + int32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to32i (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 0); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// TRNCF.SUW +rrrrr,11111110001 + wwwww,10001000000:F_I:::trncf_suw +*v850e2v3 +*v850e3v5 +"trncf.suw r, r" +{ + uint32 ans; + sim_fpu wop; + sim_fpu_status status; + + sim_fpu_32to (&wop, GR[reg2]); + TRACE_FP_INPUT_FPU1 (&wop); + + status = sim_fpu_to32u (&ans, &wop, sim_fpu_round_zero); + + check_cvt_fi(sd, status, 0); + + GR[reg3] = ans; + TRACE_FP_RESULT_WORD1 (ans); +} + +// ROTL +rrrrr,111111,iiiii+wwwww,00011000100:VII:::rotl_imm +*v850e3v5 +"rotl imm5, r, r" +{ + TRACE_ALU_INPUT1 (GR[reg2]); + v850_rotl (sd, imm5, GR[reg2], & GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + +rrrrr,111111,RRRRR+wwwww,00011000110:VII:::rotl +*v850e3v5 +"rotl r, r, r" +{ + TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); + v850_rotl (sd, GR[reg1], GR[reg2], & GR[reg3]); + TRACE_ALU_RESULT1 (GR[reg3]); +} + +// BINS +rrrrr,111111,RRRRR+bbbb,B,0001001,BBB,0:IX:::bins_top +*v850e3v5 +"bins r, + 16, - + 17, r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + v850_bins (sd, GR[reg1], bit13 + 16, bit4 + 16, & GR[reg2]); + TRACE_ALU_RESULT1 (GR[reg2]); +} + +rrrrr,111111,RRRRR+bbbb,B,0001011,BBB,0:IX:::bins_middle +*v850e3v5 +"bins r, , - + 17, r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + v850_bins (sd, GR[reg1], bit13, bit4 + 16, & GR[reg2]); + TRACE_ALU_RESULT1 (GR[reg2]); +} + +rrrrr,111111,RRRRR+bbbb,B,0001101,BBB,0:IX:::bins_bottom +*v850e3v5 +"bins r, , - + 1, r" +{ + TRACE_ALU_INPUT1 (GR[reg1]); + v850_bins (sd, GR[reg1], bit13, bit4, & GR[reg2]); + TRACE_ALU_RESULT1 (GR[reg2]); +} + +vvvvv,11111100100+xxxxx,11001111110:C:::cnvq15q30 +*v850e3v5 +"cnvq15q30 v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + if (VR[vreg2] & (1 << 15)) + v = 0x0001ffffffff0000 | VR[vreg2]; + else + v = VR[vreg2]; + VR[vreg3] = v << 15; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100110+xxxxx,11001111110:C:::cnvq30q15 +*v850e3v5 +"cnvq30q15 v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + v = ROUND_Q62_Q15 (VR[vreg2]); + SAT16 (v); + VR[vreg3] &= 0xffffffffffff0000UL; + v &= 0xffffUL; + VR[vreg3] |= v; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100101+xxxxx,11001111110:C:::cnvq31q62 +*v850e3v5 +"cnvq31q62 v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + if (VR[vreg2] & (1 << 31)) + v = 0xffffffff00000000 | VR[vreg2]; + else + v = VR[vreg2]; + VR[vreg3] = v << 31; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100111+xxxxx,11001111110:C:::cnvq62q31 +*v850e3v5 +"cnvq62q31 v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + v = ROUND_Q62_Q31 (VR[vreg2]); + SAT32 (v); + VR[vreg3] &= 0xffffffff00000000UL; + v &= 0xffffffffUL; + VR[vreg3] |= v; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111100,ii+xxxxx,11011011100:C:::dup.h +*v850e3v5 +"dup.h v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + switch (imm2) + { + case 0: v = VR[vreg2] & 0xffff; break; + case 1: v = (VR[vreg2] >> 16) & 0xffff; break; + case 2: v = (VR[vreg2] >> 32) & 0xffff; break; + case 3: v = (VR[vreg2] >> 48) & 0xffff; break; + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + v = 0; + } + + VR[vreg3] = v | (v << 16) | (v << 32) | (v << 48); + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,1111111100,i+xxxxx,11011011110:C:::dup.w +*v850e3v5 +"dup.w v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + switch (imm1) + { + case 0: v = VR[vreg2] & 0xffffffff; break; + case 1: v = (VR[vreg2] >> 32) & 0xffffffff; break; + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + v = 0; + } + + VR[vreg3] = v | (v << 32); + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111101000+xxxxx,11001111110:C:::expq31 +*v850e3v5 +"expq31 v, v" +{ + int i; + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + v = VR[vreg2] & 0xffffffff; + if (v & (1 << 31)) + { + if (v == 0x80000000) + i = 31; + else if (v == 0xffffffff) + i = 0; + else + for (i = 31; i; --i) + if ((v & (1 << i)) == 0) + break; + } + else + { + if (v == 0x7fffffff) + i = 31; + else if (v == 0x0) + i = 0; + else + for (i = 31; i; --i) + if (v & (1 << i)) + break; + } + VR[vreg3] = 31 - i; + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +rrrr,011111100000+0000011011011000:C:::modadd +*v850e3v5 +"modadd r" +{ + reg_t r; + int32 inc; + reg_t max; + + TRACE_ALU_INPUT1 (GR[reg2e]); + r = GR[reg2e]; + inc = r >> 16; + r = r & 0xffff; + max = GR[reg2e + 1]; + max &= 0xffff; + r += inc; + if (inc > 0 && r > max) + r = 0; + else if (inc < 0 && r < 0) + r = max; + GR[reg2e] = (r & 0xffff) | (inc << 16); + TRACE_ALU_RESULT1 (GR[reg2e]); +} + +vvvvv,11111111000+wwwww,11011011010:C:::mov_dw_to_gr +*v850e3v5 +"mov.dw v, r" +{ + TRACE_ALU_INPUT1 (VR[vreg2]); + GR[reg3] = VR[vreg2] & 0xffffffff; + GR[reg3 + 1] = VR[vreg2] >> 32; + TRACE_ALU_RESULT2 (GR[reg3], GR[reg3 + 1]); +} + +rrrrr,11111111100+xxxxx,11011011010:C:::mov_dw_to_vr +*v850e3v5 +"mov.dw r, v" +{ + TRACE_ALU_INPUT2 (GR[reg2], GR[reg2 + 1]); + VR[vreg3] = GR[reg2 + 1]; + VR[vreg3] <<= 32; + VR[vreg3] |= GR[reg2]; + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111000,ii+xxxxx,11011011100:C:::mov.h +*v850e3v5 +"mov.h v, v" +{ + reg64_t v = VR[vreg2]; + reg64_t mask = 0xffffUL; + int shift; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + switch (imm2) + { + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + case 0: shift = 0; break; + case 1: shift = 16; break; + case 2: shift = 32; break; + case 3: shift = 48; break; + } + + v &= mask; + VR[vreg3] &= ~ (mask << shift); + VR[vreg3] |= (v << shift); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,1111110000,i+xxxxx,11011011010:C:::mov.w.vreg_to_vreg +*v850e3v5 +"mov.w v, v" +{ + reg64_t v = VR[vreg2]; + reg64_t mask = 0xffffffffUL; + int shift; + + TRACE_ALU_INPUT1 (VR[vreg2]); + switch (imm1) + { + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + case 0: shift = 0; break; + case 1: shift = 32; break; + } + + v &= mask; + VR[vreg3] &= ~ (mask << shift); + VR[vreg3] |= (v << shift); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +rrrrr,1111111000,i+xxxxx,11011011010:C:::mov.w.reg_to_vreg +*v850e3v5 +"mov.w r, v" +{ + reg64_t v; + reg64_t mask = 0xffffffffUL; + int shift; + + TRACE_ALU_INPUT1 (GR[reg2]); + switch (imm1) + { + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + case 0: shift = 0; break; + case 1: shift = 32; break; + } + + v = GR[reg2]; + VR[vreg3] &= ~ (mask << shift); + VR[vreg3] |= (v << shift); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,1111110100,i+wwwww,11011011010:C:::mov.w.vreg_to_reg +*v850e3v5 +"mov.w v, r" +{ + TRACE_ALU_INPUT1 (VR[vreg2]); + + switch (imm1) + { + default: + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + case 0: + GR[reg3] = VR[vreg2]; + break; + case 1: + GR[reg3] = VR[vreg2] >> 32; + break; + } + + TRACE_ALU_RESULT1 (GR[reg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001101010:C:::pki16i32 +*v850e3v5 +"pki16i32 v, v, v" +{ + reg64_t v,t; + + TRACE_ALU_INPUT1 (VR[vreg1]); + + v = VR[vreg1]; + VR[vreg2] = (SEXT32 (v, 16) & 0xffffffff); + v >>= 16; + t = SEXT32 (v, 16); + VR[vreg2] |= t << 32; + + v >>= 16; + VR[vreg3] = (SEXT32 (v, 16) & 0xffffffff); + v >>= 16; + t = SEXT32 (v, 16); + VR[vreg3] |= t << 32; + + TRACE_ALU_RESULT2 (VR[vreg2], VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001100110:C:::pki16ui8 +*v850e3v5 +"pki16ui8 v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + VR[vreg3] = VR[vreg1] & 0xff; + VR[vreg3] |= ((VR[vreg1] >> 8) & 0xff00); + VR[vreg3] |= ((VR[vreg1] >> 16) & 0xff0000); + VR[vreg3] |= ((VR[vreg1] >> 24) & 0xff000000); + + VR[vreg3] |= ((VR[vreg2] << 32) & 0xff00000000UL); + VR[vreg3] |= ((VR[vreg2] << 24) & 0xff0000000000UL); + VR[vreg3] |= ((VR[vreg2] << 16) & 0xff000000000000UL); + VR[vreg3] |= ((VR[vreg2] << 8) & 0xff00000000000000UL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001100100:C:::pki32i16 +*v850e3v5 +"pki32i16 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + v = VR[vreg1] & 0xffffffff; + SAT16 (v); + VR[vreg3] = v & 0xffff; + + v = VR[vreg1] >> 32; + SAT16 (v); + VR[vreg3] |= ((v & 0xffff) << 16); + + v = VR[vreg2] & 0xffffffff; + SAT16 (v); + VR[vreg3] = ((v & 0xffff) << 32); + + v = VR[vreg2] >> 32; + SAT16 (v); + VR[vreg3] |= ((v & 0xffff) << 48); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001100010:C:::pki64i32 +*v850e3v5 +"pki64i32 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + v = VR[vreg1]; + SAT32 (v); + VR[vreg3] = v & 0xffffffff; + + v = VR[vreg2]; + SAT32 (v); + VR[vreg3] |= v << 32; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001101000:C:::pkq15q31 +*v850e3v5 +"pkq15q31 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg1]); + + v = VR[vreg1]; + VR[vreg2] = ((v & 0xffff) << 16); + VR[vreg2] |= ((v & 0xffff0000) << 32); + + VR[vreg3] = ((v & 0xffff00000000UL) >> 16); + VR[vreg3] |= ((v & 0xffff000000000000UL)); + + TRACE_ALU_RESULT2 (VR[vreg2], VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001011110:C:::pkq30q31 +*v850e3v5 +"pkq30q31 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + v = VR[vreg1]; + v <<= 1; + SAT32 (v); + VR[vreg3] = v & 0xffffffff; + + v = VR[vreg2]; + v <<= 1; + SAT32 (v); + VR[vreg3] = v << 32; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001100000:C:::pkq31q15 +*v850e3v5 +"pkq31q15 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + v = ROUND_Q31_Q15 (VR[vreg1] & 0xffffffff); + SAT16 (v); + VR[vreg3] = v & 0xffff; + + v = ROUND_Q31_Q15 (VR[vreg1] >> 32); + SAT16 (v); + VR[vreg3] |= (v & 0xffff) << 16; + + v = ROUND_Q31_Q15 (VR[vreg2] & 0xffffffff); + SAT16 (v); + VR[vreg3] |= (v & 0xffff) << 32; + + v = ROUND_Q31_Q15 (VR[vreg2] >> 32); + SAT16 (v); + VR[vreg3] |= (v & 0xffff) << 48; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001101100:C:::pkui8i16 +*v850e3v5 +"pkui8i16 v, v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg1]); + + v = VR[vreg1]; + + VR[vreg2] = v & 0x00ff; + VR[vreg2] |= (v << 8) & 0x00ff0000; + VR[vreg2] |= (v << 16) & 0x00ff00000000UL; + VR[vreg2] |= (v << 24) & 0x00ff000000000000UL; + + VR[vreg3] = (v >> 32) & 0x00ff; + VR[vreg3] |= (v >> 24) & 0x00ff0000; + VR[vreg3] |= (v >> 16) & 0x00ff00000000UL; + VR[vreg3] |= (v >> 8) & 0x00ff000000000000UL; + + TRACE_ALU_RESULT2 (VR[vreg2], VR[vreg3]); +} + +vvvvv,11111100000+xxxxx,11001111110:C:::vabs.h +*v850e3v5 +"vabs.h v, v" +{ + int shift; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + VR[vreg3] = 0; + for (shift = 0; shift < 64; shift += 16); + { + reg64_t v; + + v = VR[vreg2] >> shift; + ABS16 (v); + VR[vreg3] |= v << shift; + } + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100001+xxxxx,11001111110:C:::vabs.w +*v850e3v5 +"vabs.w v, v" +{ + reg64_t v; + + TRACE_ALU_INPUT1 (VR[vreg2]); + + v = VR[vreg2]; + ABS32 (v); + VR[vreg3] = v; + + v = VR[vreg2] >> 32; + ABS32 (v); + VR[vreg3] |= v << 32; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001011000:C:::vadd.dw +*v850e3v5 +"vadd.dw v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: saturation handling needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + VR[vreg3] = VR[vreg1] + VR[vreg2]; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000000000:C:::vadd.h +*v850e3v5 +"vadd.h v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000000010:C:::vadd.w +*v850e3v5 +"vadd.w v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000001000:C:::vadds.h +*v850e3v5 +"vadds.h v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000001010:C:::vadds.w +*v850e3v5 +"vadds.w v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000010000:C:::vaddsat.h +*v850e3v5 +"vaddsat.h v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11000010010:C:::vaddsat.w +*v850e3v5 +"vaddsat.w v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11010000000:C:::vand +*v850e3v5 +"vand v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + VR[vreg3] = VR[vreg1] & VR[vreg2]; + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001011100:C:::vbiq.h +*v850e3v5 +"vbiq.h v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT2 (VR[vreg2], VR[vreg3]); +} + +vvvvv,11111100111+xxxxx,11011011110:C:::vbswap.dw +*v850e3v5 +"vbswap.dw v, v" +{ + TRACE_ALU_INPUT1 (VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100101+xxxxx,11011011110:C:::vbswap.h +*v850e3v5 +"vbswap.h v, v" +{ + TRACE_ALU_INPUT1 (VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,11111100110+xxxxx,11011011110:C:::vbswap.w +*v850e3v5 +"vbswap.w v, v" +{ + TRACE_ALU_INPUT1 (VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001110000:C:::vcalc.h +*v850e3v5 +"vcalc.h v,v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11001110010:C:::vcalc.w +*v850e3v5 +"vcalc.w v,v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +} + +vvvvv,111111,VVVVV+xxxxx,11010110000:C:::vcmov +*v850e3v5 +"vcmov v, v, v" +{ + TRACE_ALU_INPUT2 (VR[vreg1], VR[vreg2]); + + /* FIXME: Implementation needed. */ + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIM_SIGILL); + + TRACE_ALU_RESULT1 (VR[vreg3]); +}