From 9ad55e9b25ea4423413b46be0714fc5590f85eb6 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 24 Feb 2015 17:58:50 +0000 Subject: [PATCH] Adds support for emulating V850 e3v5 instructions to the simulator. * v850.igen: Add more e3v5 support. (FMAF.S): New pattern. (FMSF.S): New pattern. (FNMAF.S): New pattern. (FNMSF.S): New pattern. (cnvq15q30): New pattern. (cnvq30q15): New pattern. (cnvq31q62): New pattern. (cnvq62q31): New pattern. (dup.h): New pattern. (dup.w): New pattern. (expq31): New pattern. (modadd): New pattern. (mov.dw): New pattern. (mov.h): New pattern. (mov.w): New pattern. (pki16i32): New pattern. (pki16ui8): New pattern. (pki32i16): New pattern. (pki64i32): New pattern. (pkq15q31): New pattern. (pkq30q31): New pattern. (pkq31q15): New pattern. (pkui8i16): New pattern. (vabs.h): New pattern. (vabs.w): New pattern. (vadd.dw): New placeholder pattern. (vadd.h): New placeholder pattern. (vadd.w): New placeholder pattern. (vadds.h): New placeholder pattern. (vadds.w): New placeholder pattern. (vaddsat.h): New placeholder pattern. (vaddsat.w): New placeholder pattern. (vand): New pattern. (vbiq.h): New placeholder pattern. (vbswap.dw): New placeholder pattern. (vbswap.h): New placeholder pattern. (vbswap.w): New placeholder pattern. (vcalc.h): New placeholder pattern. (vcalc.w): New placeholder pattern. (vcmov): New placeholder pattern. --- sim/v850/ChangeLog | 44 +++ sim/v850/v850.igen | 833 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 855 insertions(+), 22 deletions(-) diff --git a/sim/v850/ChangeLog b/sim/v850/ChangeLog index f0c9a6bdbe..7062ab24d7 100644 --- a/sim/v850/ChangeLog +++ b/sim/v850/ChangeLog @@ -1,3 +1,47 @@ +2015-02-24 Nick Clifton + + * v850.igen: Add more e3v5 support. + (FMAF.S): New pattern. + (FMSF.S): New pattern. + (FNMAF.S): New pattern. + (FNMSF.S): New pattern. + (cnvq15q30): New pattern. + (cnvq30q15): New pattern. + (cnvq31q62): New pattern. + (cnvq62q31): New pattern. + (dup.h): New pattern. + (dup.w): New pattern. + (expq31): New pattern. + (modadd): New pattern. + (mov.dw): New pattern. + (mov.h): New pattern. + (mov.w): New pattern. + (pki16i32): New pattern. + (pki16ui8): New pattern. + (pki32i16): New pattern. + (pki64i32): New pattern. + (pkq15q31): New pattern. + (pkq30q31): New pattern. + (pkq31q15): New pattern. + (pkui8i16): New pattern. + (vabs.h): New pattern. + (vabs.w): New pattern. + (vadd.dw): New placeholder pattern. + (vadd.h): New placeholder pattern. + (vadd.w): New placeholder pattern. + (vadds.h): New placeholder pattern. + (vadds.w): New placeholder pattern. + (vaddsat.h): New placeholder pattern. + (vaddsat.w): New placeholder pattern. + (vand): New pattern. + (vbiq.h): New placeholder pattern. + (vbswap.dw): New placeholder pattern. + (vbswap.h): New placeholder pattern. + (vbswap.w): New placeholder pattern. + (vcalc.h): New placeholder pattern. + (vcalc.w): New placeholder pattern. + (vcmov): New placeholder pattern. + 2014-08-19 Alan Modra * configure: Regenerate. diff --git a/sim/v850/v850.igen b/sim/v850/v850.igen index c5b41809f6..0270963c58 100644 --- a/sim/v850/v850.igen +++ b/sim/v850/v850.igen @@ -7,6 +7,7 @@ :option:::format-names:XIV,XV :option:::format-names:Z :option:::format-names:F_I +:option:::format-names:C :model:::v850:v850: @@ -29,6 +30,15 @@ :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) @@ -940,16 +950,19 @@ regID,111111,RRRRR + selID,00000100000:IX:::ldsr { uint32 sreg = GR[reg1]; TRACE_ALU_INPUT1 (GR[reg1]); - + /* FIXME: For now we ignore the selID. */ - if ( (idecode_issue == idecode_v850e2_issue - || idecode_issue == idecode_v850e3v5_issue - || idecode_issue == idecode_v850e2v3_issue) - && regID < 28) + 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: @@ -1093,7 +1106,6 @@ regID,111111,RRRRR + selID,00000100000:IX:::ldsr } - // MAC rrrrr,111111,RRRRR + wwww,0011110,mmmm,0:XI:::mac *v850e2 @@ -1473,8 +1485,6 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori COMPAT_2 (OP_1B0780 ()); } - - // RETI 0000011111100000 + 0000000101000000:X:::reti "reti" @@ -1525,7 +1535,7 @@ rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar // SASF -rrrrr,1111110,cccc + 0000001000000000:IX:::sasf +rrrrr,1111110,cccc+0000001000000000:IX:::sasf *v850e *v850e1 *v850e2 @@ -2295,12 +2305,12 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori } else { - DBPC = cia + 2; - DBPSW = PSW; - PSW = PSW | (PSW_NP | PSW_EP | PSW_ID); - PC = 0x00000060; - nia = 0x00000060; - TRACE_BRANCH0 (); + DBPC = cia + 2; + DBPSW = PSW; + PSW = PSW | (PSW_NP | PSW_EP | PSW_ID); + PC = 0x00000060; + nia = 0x00000060; + TRACE_BRANCH0 (); } } @@ -2803,7 +2813,6 @@ rrrrr,111111,RRRRR + wwwww,10001101110:F_I:::divf_s // MADDF.S rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s *v850e2v3 -*v850e3v5 "maddf.s r, r, r, r" { sim_fpu ans, wop1, wop2, wop3; @@ -2825,6 +2834,30 @@ rrrrr,111111,RRRRR + wwwww,101,W,00,WWWW,0:F_I:::maddf_s 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 @@ -2980,7 +3013,6 @@ rrrrr,111111,RRRRR + wwwww,10001101010:F_I:::minf_s // MSUBF.S rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s *v850e2v3 -*v850e3v5 "msubf.s r, r, r, r" { sim_fpu ans, wop1, wop2, wop3; @@ -3003,6 +3035,31 @@ rrrrr,111111,RRRRR + wwwww,101,W,01,WWWW,0:F_I:::msubf_s 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 @@ -3090,7 +3147,6 @@ rrrrr,11111100001 + wwwww,10001001000:F_I:::negf_s // NMADDF.S rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s *v850e2v3 -*v850e3v5 "nmaddf.s r, r, r, r" { sim_fpu ans, wop1, wop2, wop3; @@ -3114,10 +3170,35 @@ rrrrr,111111,RRRRR + wwwww,101,W,10,WWWW,0:F_I:::nmaddf_s 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 -*v850e3v5 "nmsubf.s r, r, r, r" { sim_fpu ans, wop1, wop2, wop3; @@ -3142,6 +3223,33 @@ rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s 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); +} + // RECIPF.D rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d *v850e2v3 @@ -3482,7 +3590,6 @@ rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw TRACE_FP_RESULT_WORD1 (ans); } - // TRNCF.SUW rrrrr,11111110001 + wwwww,10001000000:F_I:::trncf_suw *v850e2v3 @@ -3504,7 +3611,6 @@ rrrrr,11111110001 + wwwww,10001000000:F_I:::trncf_suw TRACE_FP_RESULT_WORD1 (ans); } - // ROTL rrrrr,111111,iiiii+wwwww,00011000100:VII:::rotl_imm *v850e3v5 @@ -3551,3 +3657,686 @@ rrrrr,111111,RRRRR+bbbb,B,0001101,BBB,0:IX:::bins_bottom 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]); +}