arch-x86: Clean up tags used in the x87 decoder.

Don't use the "E" tag when there is only a register or memory based
version of the instruction, since that decodes to both. Don't special
case the "st(1)" version of an instruction if it's just a matter of the
assembly syntax and not the instruction encoding. Don't decode based on
Mod, and then use the tag type "E" which will again decode on Mod, use
"E" for both the memory and register versions at the same time. Set the
default instruction to Inst::UD2 so that we don't have to specify it as
the default locally in each decode block. Let the "M" tag handle the Mod
= 3 case, which is built into that operand type. That's slightly
inconsistent with the "R" type which does not handle the "not 3" case,
but we can take advantage of it none the less.

There are instructions which, when decoded as the Inst format, will take
the "M" type tag and be able to drop their decoding of the Mod = 3 case,
but since they aren't Inst right now and can't sub-decode Mod on their
own, the 3 case needs to stay for now.

In most cases when dealing with x87 registers, the "dataSize" argument
to microops doesn't matter since the size doesn't change. There may be
an opportunity to consolidate the various FP microops and use dataSize
= 10 for x87 registers, although there are some nuances there that may
make that not work out.

Change-Id: Ia3ff6176796af66f6a3c463b538e750e65893a84
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42904
Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Gabe Black <gabe.black@gmail.com>
This commit is contained in:
Gabe Black
2021-03-12 01:59:42 -08:00
parent 580b22fd00
commit b60b2800ce
2 changed files with 16 additions and 73 deletions

View File

@@ -37,58 +37,35 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
format WarnUnimpl {
0x1B: decode OPCODE_OP_BOTTOM3 {
0x1B: decode OPCODE_OP_BOTTOM3 default Inst::UD2() {
0x0: decode MODRM_REG {
0x0: decode MODRM_MOD {
0x3: Inst::FADD1(Eq);
// 32-bit memory operand
default: Inst::FADD1(Md);
}
0x1: decode MODRM_MOD {
0x3: Inst::FMUL1(Eq);
default: Inst::FMUL1(Md);
}
0x0: Inst::FADD1(Ed);
0x1: Inst::FMUL1(Ed);
0x2: fcom();
0x3: fcomp();
0x4: decode MODRM_MOD {
0x3: Inst::FSUB1(Eq);
default: Inst::FSUB1(Md);
}
0x4: Inst::FSUB1(Ed);
0x5: fsubr();
0x6: decode MODRM_MOD {
0x3: Inst::FDIV1(Eq);
default: Inst::FDIV1(Md);
}
0x6: Inst::FDIV1(Ed);
0x7: fdivr();
}
0x1: decode MODRM_REG {
0x0: decode MODRM_MOD {
0x3: Inst::FLD(Eq);
// 32-bit load
default: Inst::FLD(Md);
}
0x0: Inst::FLD(Ed);
0x1: decode MODRM_MOD {
0x3: Inst::FXCH(Eq);
default: Inst::UD2();
0x3: Inst::FXCH(Rq);
}
0x2: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: fnop();
default: Inst::UD2();
}
default: Inst::FST(Ed);
}
0x3: decode MODRM_MOD {
0x3: Inst::UD2();
default: Inst::FSTP(Ed);
default: Inst::FST(Md);
}
0x3: Inst::FSTP(Md);
0x4: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: Inst::FCHS();
0x1: Inst::FABS();
0x4: ftst();
0x5: fxam();
default: Inst::UD2();
}
default: Inst::FLDENV(M);
}
@@ -156,7 +133,6 @@ format WarnUnimpl {
0x5: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x1: fucompp();
default: Inst::UD2();
}
default: fisubr();
}
@@ -191,9 +167,7 @@ format WarnUnimpl {
0x3: decode MODRM_RM {
0x2: fnclex();
0x3: fninit();
default: Inst::UD2();
}
default: Inst::UD2();
}
0x5: decode MODRM_MOD {
// 'R' insists on having a size qualifier, so I picked 'q',
@@ -204,23 +178,13 @@ format WarnUnimpl {
}
0x6: decode MODRM_MOD {
0x3: Inst::FCOMI(Rq);
default: Inst::UD2();
}
0x7: decode MODRM_MOD {
0x3: Inst::UD2();
default: Inst::FST80P(M);
}
0x7: Inst::FST80P(M);
}
//0x4: esc4();
0x4: decode MODRM_REG {
0x0: decode MODRM_MOD {
0x3: Inst::FADD2(Eq);
default: Inst::FADD2(Mq);
}
0x1: decode MODRM_MOD {
0x3: Inst::FMUL2(Eq);
default: Inst::FMUL2(Mq);
}
0x0: Inst::FADD2(Eq);
0x1: Inst::FMUL2(Eq);
0x2: decode MODRM_MOD {
0x3: Inst::UD2();
default: fcom();
@@ -271,7 +235,6 @@ format WarnUnimpl {
}
0x5: decode MODRM_MOD {
0x3: fucomp();
default: Inst::UD2();
}
0x6: decode MODRM_MOD {
0x3: Inst::UD2();
@@ -285,10 +248,7 @@ format WarnUnimpl {
//0x6: esc6();
0x6: decode MODRM_REG {
0x0: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x1: Inst::FADDP();
default: Inst::FADDP(Eq);
}
0x3: Inst::FADDP(Eq);
default: fiadd();
}
0x1: decode MODRM_MOD {
@@ -302,7 +262,6 @@ format WarnUnimpl {
0x3: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x1: fcompp();
default: Inst::UD2();
}
default: ficomp();
}
@@ -311,10 +270,7 @@ format WarnUnimpl {
default: fisub();
}
0x5: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x1: Inst::FSUBP();
default: Inst::FSUBP(Eq);
}
0x3: Inst::FSUBP(Eq);
default: fisubr();
}
0x6: decode MODRM_MOD {
@@ -332,7 +288,7 @@ format WarnUnimpl {
// The ffreep instruction isn't entirely real. It should work
// the same as ffree but then also pop the register stack.
0x3: ffreep();
default: Inst::FILD(Mw); // 16-bit int
default: Inst::FILD(Mw);
}
0x1: decode MODRM_MOD {
0x3: Inst::UD2();
@@ -349,15 +305,12 @@ format WarnUnimpl {
0x4: decode MODRM_MOD {
0x3: decode MODRM_RM {
0x0: Inst::FNSTSW(rAw);
default: Inst::UD2();
}
default: fbld();
}
0x5: decode MODRM_MOD {
// 'R' insists on having a size qualifier, so I picked 'q',
// but I don't think it has any effect
0x3: Inst::FUCOMIP(Rq);
default: Inst::FILD(Mq); // 64-bit int
default: Inst::FILD(Mq);
}
0x6: decode MODRM_MOD {
0x3: fcomip();

View File

@@ -40,14 +40,4 @@ def macroop FXCH_R
movfp sti, st(0)
movfp st(0), ufp1
};
def macroop FXCH_M
{
fault "std::make_shared<UnimpInstFault>()"
};
def macroop FXCH_P
{
fault "std::make_shared<UnimpInstFault>()"
};
'''