0x0: fnop();
default: Inst::UD2();
}
- default: fst();
+ default: Inst::FST(Ed);
}
0x3: decode MODRM_MOD {
0x3: Inst::UD2();
- default: fstp();
+ default: Inst::FSTP(Ed);
}
0x4: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x5: decode MODRM_MOD {
0x3: fucomi();
// 80-bit load
- default: fld();
+ default: Inst::FLD80(M);
}
0x6: decode MODRM_MOD {
0x3: fcomi();
}
0x7: decode MODRM_MOD {
0x3: Inst::UD2();
- default: fstp();
+ default: Inst::FST80P(M);
}
}
//0x4: esc4();
microcode = '''
def macroop FLD_M {
- ldfp ufp1, seg, sib, disp
+ ldfp87 ufp1, seg, sib, disp
movfp st(-1), ufp1, spm=-1
};
def macroop FLD_P {
rdip t7
- ldfp ufp1, seg, riprel, disp
+ ldfp87 ufp1, seg, riprel, disp
movfp st(-1), ufp1, spm=-1
};
movfp st(-1), sti, spm=-1
};
+def macroop FLD80_M {
+ ld t1, seg, sib, "DISPLACEMENT", dataSize=8
+ ld t2, seg, sib, "DISPLACEMENT + 8", dataSize=2
+ cvtint_fp80 st(-1), t1, t2, spm=-1
+};
+
+def macroop FLD80_P {
+ rdip t7
+ ld t1, seg, riprel, "DISPLACEMENT", dataSize=8
+ ld t2, seg, riprel, "DISPLACEMENT + 8", dataSize=2
+ cvtint_fp80 st(-1), t1, t2, spm=-1
+};
+
def macroop FST_R {
movfp sti, st(0)
};
def macroop FST_M {
- stfp st(0), seg, sib, disp
+ stfp87 st(0), seg, sib, disp
};
def macroop FST_P {
rdip t7
- stfp st(0), seg, riprel, disp
+ stfp87 st(0), seg, riprel, disp
};
def macroop FSTP_R {
def macroop FSTP_M {
movfp ufp1, st(0)
- stfp ufp1, seg, sib, disp
+ stfp87 ufp1, seg, sib, disp
pop87
};
def macroop FSTP_P {
movfp ufp1, st(0)
rdip t7
- stfp ufp1, seg, riprel, disp
+ stfp87 ufp1, seg, riprel, disp
pop87
};
+
+def macroop FST80P_M {
+ cvtfp80h_int t1, st(0)
+ cvtfp80l_int t2, st(0)
+ st t1, seg, sib, "DISPLACEMENT + 0", dataSize=8
+ st t2, seg, sib, "DISPLACEMENT + 8", dataSize=2
+ pop87
+};
+
+def macroop FST80P_P {
+ rdip t7
+ cvtfp80h_int t1, st(0)
+ cvtfp80l_int t2, st(0)
+ st t1, seg, riprel, "DISPLACEMENT + 0", dataSize=8
+ st t2, seg, riprel, "DISPLACEMENT + 8", dataSize=2
+ pop87
+};
+
'''
class ConvOp(FpBinaryOp):
abstract = True
op_class = 'FloatCvtOp'
- def __init__(self, dest, src1):
+ def __init__(self, dest, src1, **kwargs):
super(ConvOp, self).__init__(dest, src1, \
- "InstRegIndex(FLOATREG_MICROFP0)")
+ "InstRegIndex(FLOATREG_MICROFP0)", \
+ **kwargs)
# These probably shouldn't look at the ExtMachInst directly to figure
# out what size to use and should instead delegate that to the macroop's
SDestReg = merge(SDestReg, intSrcReg1, 4);
'''
+ # Convert two integers registers representing an 80-bit floating
+ # point number to an x87 register.
+ class cvtint_fp80(FpBinaryOp):
+ code = '''
+ uint8_t bits[10];
+ *(uint64_t *)(bits + 0) = SSrcReg1;
+ *(uint16_t *)(bits + 8) = (uint16_t)SSrcReg2;
+ FpDestReg = loadFloat80(bits);
+ '''
+
+ # Convert an x87 register (double) into extended precision and
+ # extract the highest 64 bits.
+ class cvtfp80h_int(ConvOp):
+ code = '''
+ char bits[10];
+ storeFloat80(bits, FpSrcReg1);
+ SDestReg = *(uint64_t *)(bits + 0);
+ '''
+
+ # Convert an x87 register (double) into extended precision and
+ # extract the lowest 16 bits.
+ class cvtfp80l_int(ConvOp):
+ code = '''
+ char bits[10];
+ storeFloat80(bits, FpSrcReg1);
+ SDestReg = *(uint16_t *)(bits + 8);
+ '''
+
# These need to consider size at some point. They'll always use doubles
# for the moment.
class addfp(FpBinaryOp):
defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
'Data = Mem & mask(dataSize * 8);',
'(StoreCheck << FlagShift) | Request::LOCKED')
- defineMicroLoadOp('Ldfp', 'FpData_uqw = Mem;', big = False)
+
+ defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
+
+ defineMicroLoadOp('Ldfp87', code='''
+ switch (dataSize)
+ {
+ case 4:
+ FpData_df = *(float *)&Mem;
+ break;
+ case 8:
+ FpData_df = *(double *)&Mem;
+ break;
+ default:
+ panic("Unhandled data size in LdFp87.\\n");
+ }
+ ''', big = False)
def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
global header_output
defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
mem_flags="Request::LOCKED")
- defineMicroStoreOp('Stfp', 'Mem = FpData_uqw;')
+
+ defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
+
+ defineMicroStoreOp('Stfp87', code='''
+ switch (dataSize)
+ {
+ case 4: {
+ float single(FpData_df);
+ Mem = *(uint32_t *)&single;
+ } break;
+ case 8:
+ Mem = *(uint64_t *)&FpData_df;
+ break;
+ default:
+ panic("Unhandled data size in StFp87.\\n");
+ }
+ ''')
+
defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',