summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/isa/insts/general_purpose/control_transfer/call.py4
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py18
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa82
3 files changed, 69 insertions, 35 deletions
diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
index eaaa18208..c58152ca4 100644
--- a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py
@@ -45,7 +45,7 @@ def macroop CALL_NEAR_I
limm t1, imm
rdip t7
# Check target of call
- st t7, ss, [0, t0, rsp], "-env.dataSize"
+ stis t7, ss, [0, t0, rsp], "-env.dataSize"
subi rsp, rsp, ssz
wrip t7, t1
};
@@ -58,7 +58,7 @@ def macroop CALL_NEAR_R
rdip t1
# Check target of call
- st t1, ss, [0, t0, rsp], "-env.dataSize"
+ stis t1, ss, [0, t0, rsp], "-env.dataSize"
subi rsp, rsp, ssz
wripi reg, 0
};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
index be9387ecf..a3a6eb29e 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py
@@ -40,7 +40,7 @@ def macroop POP_R {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- ld t1, ss, [1, t0, rsp], dataSize=ssz
+ ldis t1, ss, [1, t0, rsp], dataSize=ssz
addi rsp, rsp, ssz, dataSize=asz
mov reg, reg, t1
};
@@ -49,7 +49,7 @@ def macroop POP_M {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- ld t1, ss, [1, t0, rsp], dataSize=ssz
+ ldis t1, ss, [1, t0, rsp], dataSize=ssz
cda seg, sib, disp, dataSize=ssz
addi rsp, rsp, ssz, dataSize=asz
st t1, seg, sib, disp, dataSize=ssz
@@ -70,7 +70,7 @@ def macroop PUSH_R {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- st reg, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stis reg, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
subi rsp, rsp, ssz
};
@@ -79,7 +79,7 @@ def macroop PUSH_I {
.adjust_env oszIn64Override
limm t1, imm
- st t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stis t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
subi rsp, rsp, ssz
};
@@ -138,7 +138,7 @@ def macroop LEAVE {
.adjust_env oszIn64Override
mov t1, t1, rbp, dataSize=ssz
- ld rbp, ss, [1, t0, t1], dataSize=ssz
+ ldis rbp, ss, [1, t0, t1], dataSize=ssz
mov rsp, rsp, t1, dataSize=ssz
addi rsp, rsp, ssz, dataSize=ssz
};
@@ -156,7 +156,7 @@ def macroop ENTER_I_I {
# t1 is now the masked nesting level, and t2 is the amount of storage.
# Push rbp.
- st rbp, ss, [1, t0, rsp], "-env.dataSize"
+ stis rbp, ss, [1, t0, rsp], "-env.dataSize"
subi rsp, rsp, ssz
# Save the stack pointer for later
@@ -172,8 +172,8 @@ def macroop ENTER_I_I {
limm t4, "ULL(-1)", dataSize=8
topOfLoop:
- ld t5, ss, [dsz, t4, rbp]
- st t5, ss, [1, t0, rsp], "-env.dataSize"
+ ldis t5, ss, [dsz, t4, rbp]
+ stis t5, ss, [1, t0, rsp], "-env.dataSize"
subi rsp, rsp, ssz
# If we're not done yet, loop
@@ -183,7 +183,7 @@ topOfLoop:
bottomOfLoop:
# Push the old rbp onto the stack
- st t6, ss, [1, t0, rsp], "-env.dataSize"
+ stis t6, ss, [1, t0, rsp], "-env.dataSize"
subi rsp, rsp, ssz
skipLoop:
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index a22bc5fe2..6dd2b6f6b 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -315,7 +315,8 @@ def template MicroLdStSplitOpConstructor {{
let {{
class LdStOp(X86Microop):
def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ implicitStack):
self.data = data
[self.scale, self.index, self.base] = addr
self.disp = disp
@@ -331,8 +332,11 @@ let {{
self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
if nonSpec:
self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
- self.memFlags += " | (machInst.legacy.addr ? " + \
- "(AddrSizeFlagBit << FlagShift) : 0)"
+ # For implicit stack operations, we should use *not* use the
+ # alternative addressing mode for loads/stores if the prefix is set
+ if not implicitStack:
+ self.memFlags += " | (machInst.legacy.addr ? " + \
+ "(AddrSizeFlagBit << FlagShift) : 0)"
def getAllocator(self, microFlags):
allocator = '''new %(class_name)s(machInst, macrocodeBlock,
@@ -351,7 +355,8 @@ let {{
class BigLdStOp(X86Microop):
def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ implicitStack):
self.data = data
[self.scale, self.index, self.base] = addr
self.disp = disp
@@ -367,8 +372,11 @@ let {{
self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
if nonSpec:
self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
- self.memFlags += " | (machInst.legacy.addr ? " + \
- "(AddrSizeFlagBit << FlagShift) : 0)"
+ # For implicit stack operations, we should use *not* use the
+ # alternative addressing mode for loads/stores if the prefix is set
+ if not implicitStack:
+ self.memFlags += " | (machInst.legacy.addr ? " + \
+ "(AddrSizeFlagBit << FlagShift) : 0)"
def getAllocator(self, microFlags):
allocString = '''
@@ -395,9 +403,11 @@ let {{
class LdStSplitOp(LdStOp):
def __init__(self, data, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ implicitStack):
super(LdStSplitOp, self).__init__(0, segment, addr, disp,
- dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec)
+ dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec,
+ implicitStack)
(self.dataLow, self.dataHi) = data
def getAllocator(self, microFlags):
@@ -435,7 +445,8 @@ let {{
calculateEA = 'EA = SegBase + ' + segmentEAExpr
def defineMicroLoadOp(mnemonic, code, bigCode='',
- mem_flags="0", big=True, nonSpec=False):
+ mem_flags="0", big=True, nonSpec=False,
+ implicitStack=False):
global header_output
global decoder_output
global exec_output
@@ -460,17 +471,26 @@ let {{
exec_output += MicroLoadInitiateAcc.subst(iop)
exec_output += MicroLoadCompleteAcc.subst(iop)
+ if implicitStack:
+ # For instructions that implicitly access the stack, the address
+ # size is the same as the stack segment pointer size, not the
+ # address size if specified by the instruction prefix
+ addressSize = "env.stackSize"
+ else:
+ addressSize = "env.addressSize"
+
base = LdStOp
if big:
base = BigLdStOp
class LoadOp(base):
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize",
- addressSize="env.addressSize",
- atCPL0=False, prefetch=False, nonSpec=nonSpec):
+ addressSize=addressSize,
+ atCPL0=False, prefetch=False, nonSpec=nonSpec,
+ implicitStack=implicitStack):
super(LoadOp, self).__init__(data, segment, addr,
disp, dataSize, addressSize, mem_flags,
- atCPL0, prefetch, nonSpec)
+ atCPL0, prefetch, nonSpec, implicitStack)
self.className = Name
self.mnemonic = name
@@ -478,6 +498,9 @@ let {{
defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
'Data = Mem & mask(dataSize * 8);')
+ defineMicroLoadOp('Ldis', 'Data = merge(Data, Mem, dataSize);',
+ 'Data = Mem & mask(dataSize * 8);',
+ implicitStack=True)
defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
'Data = Mem & mask(dataSize * 8);',
'(StoreCheck << FlagShift)')
@@ -544,10 +567,11 @@ let {{
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize",
addressSize="env.addressSize",
- atCPL0=False, prefetch=False, nonSpec=nonSpec):
+ atCPL0=False, prefetch=False, nonSpec=nonSpec,
+ implicitStack=False):
super(LoadOp, self).__init__(data, segment, addr,
disp, dataSize, addressSize, mem_flags,
- atCPL0, prefetch, nonSpec)
+ atCPL0, prefetch, nonSpec, implicitStack)
self.className = Name
self.mnemonic = name
@@ -574,7 +598,8 @@ let {{
'(StoreCheck << FlagShift) | Request::LOCKED_RMW',
nonSpec=True)
- def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
+ def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0",
+ implicitStack=False):
global header_output
global decoder_output
global exec_output
@@ -594,20 +619,30 @@ let {{
exec_output += MicroStoreInitiateAcc.subst(iop)
exec_output += MicroStoreCompleteAcc.subst(iop)
+ if implicitStack:
+ # For instructions that implicitly access the stack, the address
+ # size is the same as the stack segment pointer size, not the
+ # address size if specified by the instruction prefix
+ addressSize = "env.stackSize"
+ else:
+ addressSize = "env.addressSize"
+
class StoreOp(LdStOp):
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize",
- addressSize="env.addressSize",
- atCPL0=False, nonSpec=False):
+ addressSize=addressSize,
+ atCPL0=False, nonSpec=False, implicitStack=implicitStack):
super(StoreOp, self).__init__(data, segment, addr, disp,
dataSize, addressSize, mem_flags, atCPL0, False,
- nonSpec)
+ nonSpec, implicitStack)
self.className = Name
self.mnemonic = name
microopClasses[name] = StoreOp
defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
+ defineMicroStoreOp('Stis', 'Mem = pick(Data, 2, dataSize);',
+ implicitStack=True)
defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
mem_flags="Request::LOCKED_RMW")
@@ -655,10 +690,10 @@ let {{
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize",
addressSize="env.addressSize",
- atCPL0=False, nonSpec=False):
+ atCPL0=False, nonSpec=False, implicitStack=False):
super(StoreOp, self).__init__(data, segment, addr, disp,
dataSize, addressSize, mem_flags, atCPL0, False,
- nonSpec)
+ nonSpec, implicitStack)
self.className = Name
self.mnemonic = name
@@ -694,7 +729,7 @@ let {{
def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"):
super(LeaOp, self).__init__(data, segment, addr, disp,
- dataSize, addressSize, "0", False, False, False)
+ dataSize, addressSize, "0", False, False, False, False)
self.className = "Lea"
self.mnemonic = "lea"
@@ -715,7 +750,7 @@ let {{
addressSize="env.addressSize"):
super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
addr, disp, dataSize, addressSize, "0", False, False,
- False)
+ False, False)
self.className = "Tia"
self.mnemonic = "tia"
@@ -727,10 +762,9 @@ let {{
addressSize="env.addressSize", atCPL0=False):
super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
- atCPL0, False, False)
+ atCPL0, False, False, False)
self.className = "Cda"
self.mnemonic = "cda"
microopClasses["cda"] = CdaOp
}};
-