Index: sim/v850/v850.igen |
diff --git a/sim/v850/v850.igen b/sim/v850/v850.igen |
index c0382bce9134f20760aab82cb540058c996916dc..9645d28cf807696c510a1da35cbb81a12aa83e70 100644 |
--- a/sim/v850/v850.igen |
+++ b/sim/v850/v850.igen |
@@ -6,6 +6,7 @@ |
:option:::format-names:XI,XII,XIII |
:option:::format-names:XIV,XV |
:option:::format-names:Z |
+:option:::format-names:F_I |
:model:::v850:v850: |
@@ -14,12 +15,22 @@ |
:model:::v850e:v850e: |
:option:::multi-sim:true |
:model:::v850e1:v850e1: |
+:option:::multi-sim:true |
+:model:::v850e2:v850e2: |
+:option:::multi-sim:true |
+:model:::v850e2v3:v850e2v3: |
// Cache macros |
:cache:::unsigned:reg1:RRRRR:(RRRRR) |
:cache:::unsigned:reg2:rrrrr:(rrrrr) |
:cache:::unsigned:reg3:wwwww:(wwwww) |
+:cache:::unsigned:reg4:W,WWWW:((W << 4) + WWWW) |
+ |
+: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) |
@@ -29,7 +40,10 @@ |
: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 |
@@ -46,6 +60,7 @@ |
:cache:::unsigned:list18:LLLL,LLLLLLLLLLLL:((LLLL << 12) + LLLLLLLLLLLL) |
:cache:::unsigned:bit3:bbb:bbb |
+:cache:::unsigned:bit4:bbbb:bbbb |
// What do we do with an illegal instruction? |
@@ -58,8 +73,7 @@ |
-// Add |
- |
+// ADD |
rrrrr,001110,RRRRR:I:::add |
"add r<reg1>, r<reg2>" |
{ |
@@ -83,6 +97,20 @@ rrrrr,110000,RRRRR + iiiiiiiiiiiiiiii:VI:::addi |
+// ADF |
+rrrrr,111111,RRRRR + wwwww,011101,cccc!13,0:XI:::adf |
+*v850e2 |
+*v850e2v3 |
+"adf %s<cccc>, r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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<reg1>, r<reg2>" |
@@ -153,12 +181,27 @@ ddddd,1011,ddd,cccc:III:::Bcond |
} |
} |
+00000111111,d,cccc + ddddddddddddddd,1:VII:::Bcond |
+"breakpoint":((disp17 == 0) && (cccc == 0x05)) |
+"b%s<cccc> <disp17>" |
+*v850e2v3 |
+{ |
+ int cond; |
+ cond = condition_met (cccc); |
+ if (cond) |
+ nia = cia + disp17; |
+ TRACE_BRANCH_INPUT1 (cond); |
+ TRACE_BRANCH_RESULT (nia); |
+} |
+ |
// BSH |
rrrrr,11111100000 + wwwww,01101000010:XII:::bsh |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"bsh r<reg2>, r<reg3>" |
{ |
unsigned32 value; |
@@ -178,10 +221,14 @@ rrrrr,11111100000 + wwwww,01101000010:XII:::bsh |
TRACE_ALU_RESULT (GR[reg3]); |
} |
+ |
+ |
// BSW |
rrrrr,11111100000 + wwwww,01101000000:XII:::bsw |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"bsw r<reg2>, r<reg3>" |
{ |
#define WORDHASNULLBYTE(x) (((x) - 0x01010101) & ~(x)&0x80808080) |
@@ -204,10 +251,14 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw |
TRACE_ALU_RESULT (GR[reg3]); |
} |
+ |
+ |
// CALLT |
0000001000,iiiiii:II:::callt |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"callt <imm6>" |
{ |
unsigned32 adr; |
@@ -221,6 +272,55 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw |
} |
+ |
+// CAXI |
+rrrrr,111111,RRRRR + wwwww,00011101110:IX:::caxi |
+*v850e2 |
+*v850e2v3 |
+"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 <bit3>, <disp16>[r<reg1>]" |
@@ -231,16 +331,21 @@ rrrrr,11111100000 + wwwww,01101000000:XII:::bsw |
rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"clr1 r<reg2>, [r<reg1>]" |
{ |
COMPAT_2 (OP_E407E0 ()); |
} |
+ |
// CTRET |
0000011111100000 + 0000000101000100:X:::ctret |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"ctret" |
{ |
nia = (CTPC & ~1); |
@@ -248,10 +353,14 @@ rrrrr,111111,RRRRR + 0000000011100100:IX:::clr1 |
TRACE_BRANCH1 (PSW); |
} |
+ |
+ |
// CMOV |
rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"cmov %s<cccc>, r<reg1>, r<reg2>, r<reg3>" |
{ |
int cond = condition_met (cccc); |
@@ -263,6 +372,8 @@ rrrrr,111111,RRRRR + wwwww,011001,cccc,0:XI:::cmov |
rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"cmov %s<cccc>, <imm5>, r<reg2>, r<reg3>" |
{ |
int cond = condition_met (cccc); |
@@ -271,6 +382,8 @@ rrrrr,111111,iiiii + wwwww,011000,cccc,0:XII:::cmov |
TRACE_ALU_RESULT (GR[reg3]); |
} |
+ |
+ |
// CMP |
rrrrr,001111,RRRRR:I:::cmp |
"cmp r<reg1>, r<reg2>" |
@@ -301,6 +414,8 @@ rrrrr,010011,iiiii:II:::cmp |
0000011001,iiiii,L + LLLLLLLLLLL,RRRRR:XIII:::dispose |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"dispose <imm5>, <list12>":RRRRR == 0 |
"dispose <imm5>, <list12>, [reg1]" |
{ |
@@ -329,10 +444,13 @@ rrrrr,010011,iiiii:II:::cmp |
} |
+ |
// DIV |
rrrrr,111111,RRRRR + wwwww,01011000000:XI:::div |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"div r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_2C007E0 ()); |
@@ -390,6 +508,8 @@ rrrrr!0,000010,RRRRR!0:I:::divh |
rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"divh r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_28007E0 ()); |
@@ -400,6 +520,8 @@ rrrrr,111111,RRRRR + wwwww,01010000000:XI:::divh |
rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"divhu r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_28207E0 ()); |
@@ -410,12 +532,60 @@ rrrrr,111111,RRRRR + wwwww,01010000010:XI:::divhu |
rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"divu r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_2C207E0 ()); |
} |
+// DIVQ |
+rrrrr,111111,RRRRR + wwwww,01011111100:XI:::divq |
+*v850e2 |
+*v850e2v3 |
+"divq r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"divq r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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]); |
+} |
+ |
+ |
// EI |
1000011111100000 + 0000000101100000:X:::ei |
"ei" |
@@ -425,6 +595,76 @@ rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu |
+// EIRET |
+0000011111100000 + 0000000101001000:X:::eiret |
+"eiret" |
+*v850e2 |
+*v850e2v3 |
+{ |
+ 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 |
+{ |
+ 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 |
+{ |
+ 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" |
@@ -434,10 +674,33 @@ rrrrr,111111,RRRRR + wwwww,01011000010:XI:::divu |
+// HSH |
+rrrrr,11111100000 + wwwww,01101000110:XII:::hsh |
+*v850e2 |
+*v850e2v3 |
+"hsh r<reg2>, r<reg3>" |
+{ |
+ 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 |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"hsw r<reg2>, r<reg3>" |
{ |
unsigned32 value; |
@@ -469,6 +732,16 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0:V:::jarl |
TRACE_BRANCH1 (GR[reg2]); |
} |
+00000010111,RRRRR!0 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jarl32 |
+*v850e2 |
+*v850e2v3 |
+"jarl <imm32>, r<reg1>" |
+{ |
+ GR[reg1] = nia; |
+ nia = (cia + imm32) & ~1; |
+ |
+ TRACE_BRANCH_RESULT (nia); |
+} |
// JMP |
@@ -479,6 +752,15 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0:V:::jarl |
TRACE_BRANCH0 (); |
} |
+00000110111,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jmp32 |
+*v850e2 |
+*v850e2v3 |
+"jmp <imm32>[r<reg1>]" |
+{ |
+ nia = (GR[reg1] + imm32) & ~1; |
+ |
+ TRACE_BRANCH_RESULT (nia); |
+} |
// JR |
@@ -490,6 +772,17 @@ rrrrr!0,11110,dddddd + ddddddddddddddd,0:V:::jarl |
} |
+// JR32 |
+00000010111,00000 + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::jr32 |
+*v850e2 |
+*v850e2v3 |
+"jr <imm32>" |
+{ |
+ nia = (cia + imm32) & ~1; |
+ |
+ TRACE_BRANCH_RESULT (nia); |
+} |
+ |
// LD |
rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b |
@@ -498,47 +791,368 @@ rrrrr,111000,RRRRR + dddddddddddddddd:VII:::ld.b |
COMPAT_2 (OP_700 ()); |
} |
+00000111100,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.b |
+"ld.b <disp23>[r<reg1>], r<reg3>" |
+*v850e2v3 |
+{ |
+ 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 <disp16>[r<reg1>], r<reg2>" |
{ |
COMPAT_2 (OP_720 ()); |
} |
+00000111100,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.h |
+*v850e2v3 |
+"ld.h <disp23>[r<reg1>], r<reg3>" |
+{ |
+ 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 <disp16>[r<reg1>], r<reg2>" |
{ |
COMPAT_2 (OP_10720 ()); |
} |
+00000111100,RRRRR+wwwww,dddddd,01001+dddddddddddddddd:XIV:::ld.w |
+*v850e2v3 |
+"ld.w <disp23>[r<reg1>], r<reg3>" |
+{ |
+ unsigned32 addr = GR[reg1] + disp23; |
+ unsigned32 result = load_data_mem (sd, addr, 4); |
+ GR[reg3] = result; |
+ TRACE_LD (addr, result); |
+} |
+ |
rrrrr!0,11110,b,RRRRR + ddddddddddddddd,1:VII:::ld.bu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"ld.bu <disp16>[r<reg1>], r<reg2>" |
{ |
COMPAT_2 (OP_10780 ()); |
} |
+00000111101,RRRRR+wwwww,ddddddd,0101+dddddddddddddddd:XIV:::ld.bu |
+*v850e2v3 |
+"ld.bu <disp23>[r<reg1>], r<reg3>" |
+{ |
+ 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 |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"ld.hu <disp16>[r<reg1>], r<reg2>" |
{ |
COMPAT_2 (OP_107E0 ()); |
} |
+00000111101,RRRRR+wwwww,dddddd,00111+dddddddddddddddd:XIV:::ld.hu |
+*v850e2v3 |
+"ld.hu <disp23>[r<reg1>], r<reg3>" |
+{ |
+ unsigned32 addr = GR[reg1] + disp23; |
+ unsigned32 result = load_data_mem (sd, addr, 2); |
+ GR[reg3] = result; |
+ TRACE_LD (addr, result); |
+} |
+ |
+ |
// LDSR |
regID,111111,RRRRR + 0000000000100000:IX:::ldsr |
"ldsr r<reg1>, s<regID>" |
{ |
+ uint32 sreg = GR[reg1]; |
TRACE_ALU_INPUT1 (GR[reg1]); |
- if (&PSW == &SR[regID]) |
- PSW = (GR[reg1] & (CPU)->psw_mask); |
+ if ((idecode_issue == idecode_v850e2_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 |
+"mac r<reg1>, r<reg2>, r<reg3e>, r<reg4e>" |
+{ |
+ 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 |
+"macu r<reg1>, r<reg2>, r<reg3e>, r<reg4e>" |
+{ |
+ 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; |
+ |
+ 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)); |
- TRACE_ALU_RESULT (SR[regID]); |
+ /* 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); |
} |
@@ -552,7 +1166,6 @@ rrrrr!0,000000,RRRRR:I:::mov |
TRACE_ALU_RESULT (GR[reg2]); |
} |
- |
rrrrr!0,010000,iiiii:II:::mov |
"mov <imm5>, r<reg2>" |
{ |
@@ -562,6 +1175,8 @@ rrrrr!0,010000,iiiii:II:::mov |
00000110001,RRRRR + iiiiiiiiiiiiiiii + IIIIIIIIIIIIIIII:VI:::mov |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"mov <imm32>, r<reg1>" |
{ |
SAVE_2; |
@@ -596,6 +1211,8 @@ rrrrr!0,110010,RRRRR + iiiiiiiiiiiiiiii:VI:::movhi |
rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"mul r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_22007E0 ()); |
@@ -604,6 +1221,8 @@ rrrrr,111111,RRRRR + wwwww,01000100000:XI:::mul |
rrrrr,111111,iiiii + wwwww,01001,IIII,00:XII:::mul |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"mul <imm9>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_24007E0 ()); |
@@ -638,6 +1257,8 @@ rrrrr!0,110111,RRRRR + iiiiiiiiiiiiiiii:VI:::mulhi |
rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"mulu r<reg1>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_22207E0 ()); |
@@ -646,6 +1267,8 @@ rrrrr,111111,RRRRR + wwwww,01000100010:XI:::mulu |
rrrrr,111111,iiiii + wwwww,01001,IIII,10:XII:::mulu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"mulu <imm9>, r<reg2>, r<reg3>" |
{ |
COMPAT_2 (OP_24207E0 ()); |
@@ -681,6 +1304,8 @@ rrrrr,000001,RRRRR:I:::not |
rrrrr,111111,RRRRR + 0000000011100010:IX:::not1 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"not1 r<reg2>, r<reg1>" |
{ |
COMPAT_2 (OP_E207E0 ()); |
@@ -710,6 +1335,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori |
0000011110,iiiii,L + LLLLLLLLLLL,00001:XIII:::prepare |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"prepare <list12>, <imm5>" |
{ |
int i; |
@@ -735,6 +1362,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori |
0000011110,iiiii,L + LLLLLLLLLLL,00011:XIII:::prepare00 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"prepare <list12>, <imm5>, sp" |
{ |
COMPAT_2 (OP_30780 ()); |
@@ -743,6 +1372,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori |
0000011110,iiiii,L + LLLLLLLLLLL,01011 + iiiiiiiiiiiiiiii:XIII:::prepare01 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"prepare <list12>, <imm5>, <uimm16>" |
{ |
COMPAT_2 (OP_B0780 ()); |
@@ -751,6 +1382,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori |
0000011110,iiiii,L + LLLLLLLLLLL,10011 + iiiiiiiiiiiiiiii:XIII:::prepare10 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"prepare <list12>, <imm5>, <uimm16>" |
{ |
COMPAT_2 (OP_130780 ()); |
@@ -759,6 +1392,8 @@ rrrrr,110100,RRRRR + iiiiiiiiiiiiiiii:VI:::ori |
0000011110,iiiii,L + LLLLLLLLLLL,11011 + iiiiiiiiiiiiiiii + dddddddddddddddd:XIII:::prepare11 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"prepare <list12>, <imm5>, <uimm32>" |
{ |
COMPAT_2 (OP_1B0780 ()); |
@@ -803,12 +1438,23 @@ rrrrr,010101,iiiii:II:::sar |
COMPAT_1 (OP_2A0 ()); |
} |
+rrrrr,111111,RRRRR + wwwww,00010100010:XI:::sar |
+*v850e2 |
+*v850e2v3 |
+"sar r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); |
+ v850_sar(sd, GR[reg1], GR[reg2], &GR[reg3]); |
+ TRACE_ALU_RESULT1 (GR[reg3]); |
+} |
// SASF |
rrrrr,1111110,cccc + 0000001000000000:IX:::sasf |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"sasf %s<cccc>, r<reg2>" |
{ |
COMPAT_2 (OP_20007E0 ()); |
@@ -816,7 +1462,6 @@ rrrrr,1111110,cccc + 0000001000000000:IX:::sasf |
- |
// SATADD |
rrrrr!0,000110,RRRRR:I:::satadd |
"satadd r<reg1>, r<reg2>" |
@@ -830,6 +1475,16 @@ rrrrr!0,010001,iiiii:II:::satadd |
COMPAT_1 (OP_220 ()); |
} |
+rrrrr,111111,RRRRR + wwwww,01110111010:XI:::satadd |
+*v850e2 |
+*v850e2v3 |
+"satadd r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); |
+ v850_satadd (sd, GR[reg1], GR[reg2], &GR[reg3]); |
+ TRACE_ALU_RESULT1 (GR[reg3]); |
+} |
+ |
// SATSUB |
@@ -839,6 +1494,16 @@ rrrrr!0,000101,RRRRR:I:::satsub |
COMPAT_1 (OP_A0 ()); |
} |
+rrrrr,111111,RRRRR + wwwww,01110011010:XI:::satsub |
+*v850e2 |
+*v850e2v3 |
+"satsub r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ TRACE_ALU_INPUT2 (GR[reg1], GR[reg2]); |
+ v850_satsub (sd, GR[reg1], GR[reg2], &GR[reg3]); |
+ TRACE_ALU_RESULT1 (GR[reg3]); |
+} |
+ |
// SATSUBI |
@@ -859,6 +1524,234 @@ rrrrr!0,000100,RRRRR:I:::satsubr |
+//SBF |
+rrrrr,111111,RRRRR + wwwww,011100,cccc!13,0:XI:::sbf |
+*v850e2 |
+*v850e2v3 |
+"sbf %s<cccc>, r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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]); |
+} |
+ |
+ |
+ |
+// SCH0L |
+rrrrr,11111100000 + wwwww,01101100100:IX:::sch0l |
+*v850e2 |
+*v850e2v3 |
+"sch0l r<reg2>, r<reg3>" |
+{ |
+ 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 == 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 |
+"sch0r r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"sch1l r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"sch1r r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"shl r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"shr r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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<cccc>, r<reg2>" |
@@ -878,6 +1771,8 @@ rrrrr,1111110,cccc + 0000000000000000:IX:::setf |
rrrrr,111111,RRRRR + 0000000011100000:IX:::set1 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"set1 r<reg2>, [r<reg1>]" |
{ |
COMPAT_2 (OP_E007E0 ()); |
@@ -966,6 +1861,8 @@ rrrrr,1010,dddddd,0:IV:::sld.w |
rrrrr!0,0000110,dddd:IV:::sld.bu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"sld.b <disp4>[ep], r<reg2>":(PSW & PSW_US) |
"sld.bu <disp4>[ep], r<reg2>" |
{ |
@@ -987,6 +1884,8 @@ rrrrr!0,0000110,dddd:IV:::sld.bu |
rrrrr!0,0000111,dddd:IV:::sld.hu |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"sld.h <disp5>[ep], r<reg2>":(PSW & PSW_US) |
"sld.hu <disp5>[ep], r<reg2>" |
{ |
@@ -1005,6 +1904,8 @@ rrrrr!0,0000111,dddd:IV:::sld.hu |
} |
} |
+ |
+ |
// SST |
rrrrr,0111,ddddddd:IV:::sst.b |
"sst.b r<reg2>, <disp7>[ep]" |
@@ -1031,24 +1932,108 @@ rrrrr,111010,RRRRR + dddddddddddddddd:VII:::st.b |
COMPAT_2 (OP_740 ()); |
} |
+00000111100,RRRRR + wwwww,ddddddd,1101 + dddddddddddddddd:XIV:::st.b |
+*v850e2v3 |
+"st.b r<reg3>, <disp23>[r<reg1>]" |
+{ |
+ 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<reg2>, <disp16>[r<reg1>]" |
{ |
COMPAT_2 (OP_760 ()); |
} |
-rrrrr,111011,RRRRR + ddddddddddddddd,1:VII:::st.w |
+00000111101,RRRRR+wwwww,dddddd,01101+dddddddddddddddd:XIV:::st.h |
+*v850e2v3 |
+"st.h r<reg3>, <disp23>[r<reg1>]" |
+{ |
+ 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<reg2>, <disp16>[r<reg1>]" |
{ |
COMPAT_2 (OP_10760 ()); |
} |
+00000111100,RRRRR+wwwww,dddddd,01111+dddddddddddddddd:XIV:::st.w |
+*v850e2v3 |
+"st.w r<reg3>, <disp23>[r<reg1>]" |
+{ |
+ unsigned32 addr = GR[reg1] + disp23; |
+ store_data_mem (sd, addr, 4, GR[reg3]); |
+ TRACE_ST (addr, GR[reg3]); |
+} |
+ |
+ |
// STSR |
rrrrr,111111,regID + 0000000001000000:IX:::stsr |
"stsr s<regID>, r<reg2>" |
{ |
- TRACE_ALU_INPUT1 (SR[regID]); |
- GR[reg2] = SR[regID]; |
+ uint32 sreg = 0; |
+ |
+ if ((idecode_issue == idecode_v850e2_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]); |
} |
@@ -1070,6 +2055,8 @@ rrrrr,001100,RRRRR:I:::subr |
00000000010,RRRRR:I:::switch |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"switch r<reg1>" |
{ |
unsigned long adr; |
@@ -1084,6 +2071,8 @@ rrrrr,001100,RRRRR:I:::subr |
00000000101,RRRRR:I:::sxb |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"sxb r<reg1>" |
{ |
TRACE_ALU_INPUT1 (GR[reg1]); |
@@ -1095,6 +2084,8 @@ rrrrr,001100,RRRRR:I:::subr |
00000000111,RRRRR:I:::sxh |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"sxh r<reg1>" |
{ |
TRACE_ALU_INPUT1 (GR[reg1]); |
@@ -1126,6 +2117,8 @@ rrrrr,001011,RRRRR:I:::tst |
rrrrr,111111,RRRRR + 0000000011100110:IX:::tst1 |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"tst1 r<reg2>, [r<reg1>]" |
{ |
COMPAT_2 (OP_E607E0 ()); |
@@ -1149,6 +2142,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori |
00000000100,RRRRR:I:::zxb |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"zxb r<reg1>" |
{ |
TRACE_ALU_INPUT1 (GR[reg1]); |
@@ -1160,6 +2155,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori |
00000000110,RRRRR:I:::zxh |
*v850e |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"zxh r<reg1>" |
{ |
TRACE_ALU_INPUT1 (GR[reg1]); |
@@ -1178,6 +2175,8 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori |
11111,000010,00000:I:::dbtrap |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"dbtrap" |
{ |
DBPC = cia + 2; |
@@ -1197,9 +2196,1069 @@ rrrrr,110101,RRRRR + iiiiiiiiiiiiiiii:VI:::xori |
// Return from debug trap: 0x146007e0 |
0000011111100000 + 0000000101000110:X:::dbret |
*v850e1 |
+*v850e2 |
+*v850e2v3 |
"dbret" |
{ |
nia = DBPC; |
PSW = DBPSW; |
TRACE_BRANCH1 (PSW); |
} |
+ |
+ |
+// |
+// FLOAT |
+// |
+ |
+// Map condition code to a string |
+:%s::::FFFF:int FFFF |
+{ |
+ 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 |
+"absf.d r<reg2e>, r<reg3e>" |
+{ |
+ 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_abs (&ans, &wop); |
+ check_invalid_snan(sd, status, 1); |
+ |
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); |
+ |
+ TRACE_FP_RESULT_FPU1 (&ans); |
+} |
+ |
+// ABSF.S |
+rrrrr,11111100000 + wwwww,10001001000:F_I:::absf_s |
+*v850e2v3 |
+"absf.s r<reg2>, r<reg3>" |
+{ |
+ 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); |
+} |
+ |
+// ADDF.D |
+rrrr,0111111,RRRR,0 + wwww,010001110000:F_I:::addf_d |
+*v850e2v3 |
+"addf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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_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); |
+} |
+ |
+// ADDF.S |
+rrrrr,111111,RRRRR + wwwww,10001100000:F_I:::addf_s |
+*v850e2v3 |
+"addf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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_add (&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); |
+} |
+ |
+// CMOVF.D |
+rrrr,0111111,RRRR,0 + wwww!0,01000001,bbb,0:F_I:::cmovf_d |
+*v850e2v3 |
+"cmovf.d <bbb>, r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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); |
+ |
+ 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 + wwwww!0,1000000,bbb,0:F_I:::cmovf_s |
+*v850e2v3 |
+"cmovf.d <bbb>, r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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); |
+ |
+ 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 |
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>":(bbb == 0) |
+"cmpf.d %s<FFFF>, r<reg1e>, r<reg2e>, <bbb>" |
+{ |
+ 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 (&wop1, &wop2); |
+ |
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 1); |
+ |
+ if (result) |
+ SET_FPCC(bbb); |
+ else |
+ CLEAR_FPCC(bbb); |
+ |
+ TRACE_FP_RESULT_BOOL (result); |
+} |
+ |
+// CMPF.S |
+rrrrr,111111,RRRRR + 0,FFFF,1000010,bbb,0:F_I:::cmpf_s |
+*v850e2v3 |
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>":(bbb == 0) |
+"cmpf.s %s<FFFF>, r<reg1>, r<reg2>, <bbb>" |
+{ |
+ int result; |
+ sim_fpu wop1; |
+ sim_fpu wop2; |
+ |
+ sim_fpu_32to( &wop1, GR[reg1] ); |
+ sim_fpu_32to( &wop2, GR[reg2] ); |
+ TRACE_FP_INPUT_FPU2 (&wop1, &wop2); |
+ |
+ result = v850_float_compare(sd, FFFF, wop1, wop2, 0); |
+ |
+ if (result) |
+ SET_FPCC(bbb); |
+ else |
+ CLEAR_FPCC(bbb); |
+ |
+ TRACE_FP_RESULT_BOOL (result); |
+} |
+ |
+// CVTF.DL |
+rrrr,011111100100 + wwww,010001010100:F_I:::cvtf_dl |
+*v850e2v3 |
+"cvtf.dl r<reg2e>, r<reg3e>" |
+{ |
+ 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_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 |
+"cvtf.ds r<reg2e>, r<reg3>" |
+{ |
+ 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 |
+"cvtf.dw r<reg2e>, r<reg3>" |
+{ |
+ 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_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 |
+"cvtf.ld r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"cvtf.ls r<reg2e>, r<reg3>" |
+{ |
+ 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 |
+"cvtf.sd r<reg2>, r<reg3e>" |
+{ |
+ 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 |
+"cvtf.sl r<reg2>, r<reg3e>" |
+{ |
+ 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 |
+"cvtf.sw r<reg2>, r<reg3>" |
+{ |
+ uint32 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 |
+"cvtf.wd r<reg2>, r<reg3e>" |
+{ |
+ 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 |
+"cvtf.ws r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"divf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"divf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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<reg1>, r<reg2>, r<reg3>, r<reg4>" |
+{ |
+ 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_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); |
+} |
+ |
+// MAXF.D |
+rrrr,0111111,RRRR,0 + wwww,010001111000:F_I:::maxf_d |
+*v850e2v3 |
+"maxf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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); |
+ } |
+ |
+ sim_fpu_to232 (&GR[reg3e+1], &GR[reg3e], &ans); |
+ TRACE_FP_RESULT_FPU1 (&ans); |
+} |
+ |
+// MAXF.S |
+rrrrr,111111,RRRRR + wwwww,10001101000:F_I:::maxf_s |
+*v850e2v3 |
+"maxf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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); |
+ } |
+ |
+ sim_fpu_to32 (&GR[reg3], &ans); |
+ TRACE_FP_RESULT_FPU1 (&ans); |
+} |
+ |
+// MINF.D |
+rrrr,0111111,RRRR,0 + wwww,010001111010:F_I:::minf_d |
+*v850e2v3 |
+"minf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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_min (&ans, &wop1, &wop2); |
+ } |
+ |
+ 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 |
+"minf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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_min (&ans, &wop1, &wop2); |
+ } |
+ |
+ 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<reg1>, r<reg2>, r<reg3>, r<reg4>" |
+{ |
+ 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); |
+} |
+ |
+// MULF.D |
+rrrr,0111111,RRRR,0 + wwww,010001110100:F_I:::mulf_d |
+*v850e2v3 |
+"mulf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"mulf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"negf.d r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"negf.s r<reg2>, r<reg3>" |
+{ |
+ 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<reg1>, r<reg2>, r<reg3>, r<reg4>" |
+{ |
+ 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_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); |
+} |
+ |
+// NMSUBF.S |
+rrrrr,111111,RRRRR + wwwww,101,W,11,WWWW,0:F_I:::nmsubf_s |
+*v850e2v3 |
+"nmsubf.s r<reg1>, r<reg2>, r<reg3>, r<reg4>" |
+{ |
+ 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); |
+} |
+ |
+// RECIPF.D |
+rrrr,011111100001 + wwww,010001011110:F_I:::recipf.d |
+*v850e2v3 |
+"recipf.d r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"recipf.s r<reg2>, r<reg3>" |
+{ |
+ 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); |
+} |
+ |
+// RSQRTF.D |
+rrrr,011111100010 + wwww,010001011110:F_I:::rsqrtf.d |
+*v850e2v3 |
+"rsqrtf.d r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"rsqrtf.s r<reg2>, r<reg3>" |
+{ |
+ 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); |
+ |
+ sim_fpu_to32 (&GR[reg3], &ans); |
+ TRACE_FP_RESULT_FPU1 (&ans); |
+} |
+ |
+// SQRTF.D |
+rrrr,011111100000 + wwww,010001011110:F_I:::sqrtf.d |
+*v850e2v3 |
+"sqrtf.d r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"sqrtf.s r<reg2>, r<reg3>" |
+{ |
+ 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); |
+} |
+ |
+// SUBF.D |
+rrrr,0111111,RRRR,0 + wwww,010001110010:F_I:::subf.d |
+*v850e2v3 |
+"subf.d r<reg1e>, r<reg2e>, r<reg3e>" |
+{ |
+ 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 |
+"subf.s r<reg1>, r<reg2>, r<reg3>" |
+{ |
+ 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 |
+"trfsr":(bbb == 0) |
+"trfsr <bbb>" |
+{ |
+ 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 |
+"trncf.dl r<reg2e>, r<reg3e>" |
+{ |
+ 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, sim_fpu_round_zero, sim_fpu_denorm_zero); |
+ 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.DW |
+rrrr,011111100001 + wwwww,10001010000:F_I:::trncf_dw |
+*v850e2v3 |
+"trncf.dw r<reg2e>, r<reg3>" |
+{ |
+ 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_round_32 (&wop, sim_fpu_round_zero, sim_fpu_denorm_zero); |
+ 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.SL |
+rrrrr,11111100001 + wwww,010001000100:F_I:::trncf_sl |
+*v850e2v3 |
+"trncf.sl r<reg2>, r<reg3e>" |
+{ |
+ 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, sim_fpu_round_zero, sim_fpu_denorm_zero); |
+ 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.SW |
+rrrrr,11111100001 + wwwww,10001000000:F_I:::trncf_sw |
+*v850e2v3 |
+"trncf.sw r<reg2>, r<reg3>" |
+{ |
+ uint32 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, sim_fpu_round_zero, 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); |
+} |
+ |