X86: Implement some bit testing instructions.
authorGabe Black <gblack@eecs.umich.edu>
Mon, 12 Nov 2007 22:38:53 +0000 (14:38 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Mon, 12 Nov 2007 22:38:53 +0000 (14:38 -0800)
--HG--
extra : convert_revision : 54585e276e44322be9c56af0b2eabfe8d4b3e430

src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_test.py

index 30034a30560d6103b1a95e6e31d495b562e3d8b6..233a5602de62764e173e4d40f4d2f82c6b948ec3 100644 (file)
                 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();
                 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();
                 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
             }
             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
index e950f008ac687a4101139113bfd6a0abf1e57110..883ec4411d2a7ce3ae657ea3471c45cd7653b968 100644 (file)
 #
 # 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
+};
+'''