X86: Implement some bit testing instructions.

--HG--
extra : convert_revision : 54585e276e44322be9c56af0b2eabfe8d4b3e430
This commit is contained in:
Gabe Black 2007-11-12 14:38:53 -08:00
parent f9ddb894dd
commit 4d4d2883f9
2 changed files with 254 additions and 24 deletions

View file

@ -657,7 +657,7 @@
0x0: push_fs();
0x1: pop_fs();
0x2: Inst::CPUID(rAd);
0x3: bt_Ev_Gv();
0x3: Inst::BT(Ev,Gv);
0x4: shld_Ev_Gv_Ib();
0x5: shld_Ev_Gv_rCl();
0x6: xbts_and_cmpxchg();
@ -667,7 +667,7 @@
0x0: push_gs();
0x1: pop_gs();
0x2: rsm_smm();
0x3: bts_Ev_Gv();
0x3: Inst::BTS(Ev,Gv);
0x4: shrd_Ev_Gv_Ib();
0x5: shrd_Ev_Gv_rCl();
//0x6: group16();
@ -691,7 +691,7 @@
0x0: Inst::CMPXCHG(Eb,Gb);
0x1: Inst::CMPXCHG(Ev,Gv);
0x2: lss_Gz_Mp();
0x3: btr_Ev_Gv();
0x3: Inst::BTR(Ev,Gv);
0x4: lfs_Gz_Mp();
0x5: lgs_Gz_Mp();
//The size of the second operand in these instructions should
@ -702,17 +702,19 @@
}
0x17: decode OPCODE_OP_BOTTOM3 {
0x0: jmpe_Jz(); // IA-64?
//0x1: group11_UD2();
0x1: Inst::UD2();
//0x2: group8_Ev_Ib();
0x2: decode MODRM_REG {
0x4: bt_Ev_Ib();
0x5: bts_Ev_Ib();
0x6: btr_Ev_Ib();
0x7: btc_Ev_Ib();
default: Inst::UD2();
format Inst {
//0x1: group11_UD2();
0x1: UD2();
//0x2: group8_Ev_Ib();
0x2: decode MODRM_REG {
0x4: BT(Ev,Ib);
0x5: BTS(Ev,Ib);
0x6: BTR(Ev,Ib);
0x7: BTC(Ev,Ib);
default: UD2();
}
0x3: BTC(Ev,Gv);
}
0x3: btc_Ev_Gv();
0x4: bsf_Gv_Ev();
0x5: bsr_Gv_Ev();
//The size of the second operand in these instructions should

View file

@ -53,14 +53,242 @@
#
# Authors: Gabe Black
microcode = ""
#let {{
# class BT(Inst):
# "GenFault ${new UnimpInstFault}"
# class BTC(Inst):
# "GenFault ${new UnimpInstFault}"
# class BTR(Inst):
# "GenFault ${new UnimpInstFault}"
# class BTS(Inst):
# "GenFault ${new UnimpInstFault}"
#}};
microcode = '''
def macroop BT_R_I {
sexti t0, reg, imm, flags=(CF,)
};
def macroop BT_M_I {
limm t1, imm
# This fudges just a tiny bit, but it's reasonable to expect the
# microcode generation logic to have the log of the various sizes
# floating around as well.
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
ld t1, seg, [scale, index, t2], disp
sexti t0, t1, imm, flags=(CF,)
};
def macroop BT_P_I {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
ld t1, seg, [1, t2, t7]
sexti t0, t1, imm, flags=(CF,)
};
def macroop BT_R_R {
sext t0, reg, regm, flags=(CF,)
};
def macroop BT_M_R {
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
ld t1, seg, [scale, index, t2], disp
sext t0, t1, reg, flags=(CF,)
};
def macroop BT_P_R {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
ld t1, seg, [1, t2, t7]
sext t0, t1, reg, flags=(CF,)
};
def macroop BTC_R_I {
sexti t0, reg, imm, flags=(CF,)
limm t1, 1
roli t1, t1, imm
xor reg, reg, t1
};
def macroop BTC_M_I {
limm t1, imm
# This fudges just a tiny bit, but it's reasonable to expect the
# microcode generation logic to have the log of the various sizes
# floating around as well.
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, 1
roli t3, t3, imm
ldst t1, seg, [scale, index, t2], disp
sexti t0, t1, imm, flags=(CF,)
xor t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTC_P_I {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, 1
roli t3, t3, imm
ldst t1, seg, [1, t2, t7]
sexti t0, t1, imm, flags=(CF,)
xor t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTC_R_R {
sext t0, reg, regm, flags=(CF,)
limm t1, 1
rol t1, t1, regm
xor reg, reg, t1
};
def macroop BTC_M_R {
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, 1
rol t3, t3, reg
ldst t1, seg, [scale, index, t2], disp
sext t0, t1, reg, flags=(CF,)
xor t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTC_P_R {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, 1
rol t3, t3, reg
ldst t1, seg, [1, t2, t7]
sext t0, t1, reg, flags=(CF,)
xor t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTR_R_I {
sexti t0, reg, imm, flags=(CF,)
limm t1, "(uint64_t(-(2ULL)))"
roli t1, t1, imm
and reg, reg, t1
};
def macroop BTR_M_I {
limm t1, imm
# This fudges just a tiny bit, but it's reasonable to expect the
# microcode generation logic to have the log of the various sizes
# floating around as well.
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, "(uint64_t(-(2ULL)))"
roli t3, t3, imm
ldst t1, seg, [scale, index, t2], disp
sexti t0, t1, imm, flags=(CF,)
and t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTR_P_I {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, "(uint64_t(-(2ULL)))"
roli t3, t3, imm
ldst t1, seg, [1, t2, t7]
sexti t0, t1, imm, flags=(CF,)
and t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTR_R_R {
sext t0, reg, regm, flags=(CF,)
limm t1, "(uint64_t(-(2ULL)))"
rol t1, t1, regm
and reg, reg, t1
};
def macroop BTR_M_R {
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, "(uint64_t(-(2ULL)))"
rol t3, t3, reg
ldst t1, seg, [scale, index, t2], disp
sext t0, t1, reg, flags=(CF,)
and t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTR_P_R {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, "(uint64_t(-(2ULL)))"
rol t3, t3, reg
ldst t1, seg, [1, t2, t7]
sext t0, t1, reg, flags=(CF,)
and t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTS_R_I {
sexti t0, reg, imm, flags=(CF,)
limm t1, 1
roli t1, t1, imm
or reg, reg, t1
};
def macroop BTS_M_I {
limm t1, imm
# This fudges just a tiny bit, but it's reasonable to expect the
# microcode generation logic to have the log of the various sizes
# floating around as well.
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, 1
roli t3, t3, imm
ldst t1, seg, [scale, index, t2], disp
sexti t0, t1, imm, flags=(CF,)
or t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTS_P_I {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, 1
roli t3, t3, imm
ldst t1, seg, [1, t2, t7]
sexti t0, t1, imm, flags=(CF,)
or t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTS_R_R {
sext t0, reg, regm, flags=(CF,)
limm t1, 1
rol t1, t1, regm
or reg, reg, t1
};
def macroop BTS_M_R {
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
add t2, t2, base
limm t3, 1
rol t3, t3, reg
ldst t1, seg, [scale, index, t2], disp
sext t0, t1, reg, flags=(CF,)
or t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
def macroop BTS_P_R {
rdip t7
limm t1, imm
srai t2, t1, "(env.dataSize == 8) ? 3 : ((env.dataSize == 4) ? 2 : 1)"
limm t3, 1
rol t3, t3, reg
ldst t1, seg, [1, t2, t7]
sext t0, t1, reg, flags=(CF,)
or t1, t1, t3
st t1, seg, [scale, index, t2], disp
};
'''