arch-x86: Add insts used in newer libstdc++ rehashing

For newer versions of libstdc++ (Like the one in the
ubuntu-20.04_all-dependencies docker image), the variables used when
rehashing, e.g., std::unordered_maps have been extended. This resulted
in the rehashing function using different, unimplemented, instructions.

Because these instructions are unimplemented, it resulted in a
std::bad_alloc exception when inserting into an unordered_map

This patchset implements the following instructions:
FCOMI, a floating point comparison instruction, using the compfp
microop. The implementation mirrors that of the FUCOMI instruction
(another floating point comparison instruction)

FSUBRP, a reverse subtraction instruction, is implemented using the
subfp microop like the FSUBP does, but with the operands flipped
accordingly.

FISTP, an instruction to convert a float to int and then store, is
implemented by using a conversion microop (cvtf_d2i) and then a store.
The cvtf_d2i microop is re-written to handle multple data sizes, as is
required by the FISTP instruction.

Change-Id: I85c57acace1f7a547b0a97ec3a0f0500909c5d2a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42443
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Kyle Roarty
2021-03-07 14:59:26 -06:00
parent e24d4b8659
commit 352ce704f1
6 changed files with 37 additions and 13 deletions

View File

@@ -54,6 +54,7 @@ class FpOp : public X86MicroopBase
const RegIndex dest;
const uint8_t dataSize;
const int8_t spm;
RegIndex foldOBit;
// Constructor
FpOp(ExtMachInst _machInst,
@@ -66,7 +67,9 @@ class FpOp : public X86MicroopBase
__opClass),
src1(_src1.index()), src2(_src2.index()), dest(_dest.index()),
dataSize(_dataSize), spm(_spm)
{}
{
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
}
std::string generateDisassembly(
Addr pc, const Loader::SymbolTable *symtab) const override;

View File

@@ -185,7 +185,7 @@ format WarnUnimpl {
}
0x3: decode MODRM_MOD {
0x3: fcmovnu();
default: fistp();
default: Inst::FISTP(Md);
}
0x4: decode MODRM_MOD {
0x3: decode MODRM_RM {
@@ -203,7 +203,7 @@ format WarnUnimpl {
default: Inst::FLD80(M);
}
0x6: decode MODRM_MOD {
0x3: fcomi();
0x3: Inst::FCOMI(Rq);
default: Inst::UD2();
}
0x7: decode MODRM_MOD {
@@ -307,7 +307,7 @@ format WarnUnimpl {
default: ficomp();
}
0x4: decode MODRM_MOD {
0x3: fsubrp();
0x3: Inst::FSUBRP(Rq);
default: fisub();
}
0x5: decode MODRM_MOD {
@@ -344,7 +344,7 @@ format WarnUnimpl {
}
0x3: decode MODRM_MOD {
0x3: Inst::UD2();
default: fistp();
default: Inst::FISTP(Mw);
}
0x4: decode MODRM_MOD {
0x3: decode MODRM_RM {
@@ -365,7 +365,7 @@ format WarnUnimpl {
}
0x7: decode MODRM_MOD {
0x3: Inst::UD2();
default: fistp();
default: Inst::FISTP(Mq);
}
}
}

View File

@@ -91,8 +91,12 @@ def macroop FSUBP_P
fault "std::make_shared<UnimpInstFault>()"
};
def macroop FSUBRP_R
{
subfp sti, st(0), sti, spm=1
};
# FISUB
# FSUBR
# FSUBRP
# FISUBR
'''

View File

@@ -37,6 +37,11 @@ microcode = '''
# FCOM
# FCOMP
# FCOMPP
# FCOMI
# FCOMIP
def macroop FCOMI_R
{
compfp st(0), sti
};
'''

View File

@@ -50,6 +50,21 @@ def macroop FILD_P {
};
# FIST
# FISTP
def macroop FISTP_M
{
cvtf_d2i t1, st(0)
st t1, seg, sib, disp
pop87
};
def macroop FISTP_P
{
rdip t7
cvtf_d2i t1, st(0)
st t1, seg, riprel, disp
pop87
};
# FISTTP
'''

View File

@@ -322,10 +322,7 @@ let {{
class cvtf_d2i(ConvOp):
code = '''
int64_t intSrcReg1 = static_cast<int64_t>(FpSrcReg1);
if (REX_W)
SDestReg = intSrcReg1;
else
SDestReg = merge(SDestReg, intSrcReg1, 4);
DestReg = merge(DestReg, intSrcReg1, dataSize);
'''
# Convert two integers registers representing an 80-bit floating