summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-07-20 23:16:03 -0700
committerGabe Black <gblack@eecs.umich.edu>2007-07-20 23:16:03 -0700
commitfc1b7d62b7e8e5cf59956875720dbd1deb68af93 (patch)
tree72af2ec10ae733a6dea67a39141602c2f379ba32 /src/arch/x86/isa
parent009df5ff1e19276433975fddd43a306ff653a20e (diff)
downloadgem5-fc1b7d62b7e8e5cf59956875720dbd1deb68af93.tar.xz
Fixed the distinction between far and near versions of jmp, call and ret. Implemented some shifts, rotates, and pushes.
--HG-- extra : convert_revision : fcb06189ff213e82da16ac43231feb308cb3a285
Diffstat (limited to 'src/arch/x86/isa')
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa54
-rw-r--r--src/arch/x86/isa/insts/control_transfer/call.py39
-rw-r--r--src/arch/x86/isa/insts/control_transfer/jump.py6
-rw-r--r--src/arch/x86/isa/insts/data_transfer/stack_operations.py19
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/rotate.py46
-rw-r--r--src/arch/x86/isa/insts/rotate_and_shift/shift.py40
-rw-r--r--src/arch/x86/isa/microops/regop.isa106
7 files changed, 245 insertions, 65 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 2c2d68785..329a03f40 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -306,7 +306,7 @@
0x1: cwd_or_cdq_or_cqo_rAX_rDX();
0x2: decode MODE_SUBMODE {
0x0: Inst::UD2();
- default: call_Ap();
+ default: call_far_Ap();
}
0x3: fwait(); //aka wait
0x4: pushf_Fv();
@@ -356,25 +356,25 @@
0x18: decode OPCODE_OP_BOTTOM3 {
//0x0: group2_Eb_Ib();
0x0: decode MODRM_REG {
- 0x0: rol_Eb_Ib();
- 0x1: ror_Eb_Ib();
+ 0x0: Inst::ROL(Eb,Ib);
+ 0x1: Inst::ROR(Eb,Ib);
0x2: rcl_Eb_Ib();
0x3: rcr_Eb_Ib();
0x4: Inst::SAL(Eb,Ib);
- 0x5: shr_Eb_Ib();
+ 0x5: Inst::SHR(Eb,Ib);
0x6: Inst::SAL(Eb,Ib);
- 0x7: sar_Eb_Ib();
+ 0x7: Inst::SAR(Eb,Ib);
}
//0x1: group2_Ev_Ib();
0x1: decode MODRM_REG {
- 0x0: rol_Ev_Ib();
- 0x1: ror_Ev_Ib();
+ 0x0: Inst::ROL(Ev,Ib);
+ 0x1: Inst::ROR(Ev,Ib);
0x2: rcl_Ev_Ib();
0x3: rcr_Ev_Ib();
0x4: Inst::SAL(Ev,Ib);
- 0x5: shr_Ev_Ib();
+ 0x5: Inst::SHR(Ev,Ib);
0x6: Inst::SAL(Ev,Ib);
- 0x7: sar_Ev_Ib();
+ 0x7: Inst::SAR(Ev,Ib);
}
0x2: ret_near_Iw();
0x3: Inst::RET_NEAR();
@@ -452,7 +452,7 @@
0x1: Inst::JMP(Jz);
0x2: decode MODE_SUBMODE {
0x0: Inst::UD2();
- default: jmp_Ap();
+ default: jmp_far_Ap();
}
0x3: Inst::JMP(Jb);
0x4: in_Al_Dx();
@@ -480,22 +480,24 @@
0x3: sti();
0x4: cld();
0x5: std();
- //0x6: group4();
- 0x6: decode MODRM_REG {
- 0x0: Inst::INC(Eb);
- 0x1: Inst::DEC(Eb);
- default: Inst::UD2();
- }
- //0x7: group5();
- 0x7: decode MODRM_REG {
- 0x0: Inst::INC(Ev);
- 0x1: Inst::DEC(Ev);
- 0x2: call_Ev();
- 0x3: call_Mp();
- 0x4: jmp_Ev();
- 0x5: jmp_Mp();
- 0x6: push_Ev();
- 0x7: Inst::UD2();
+ format Inst {
+ //0x6: group4();
+ 0x6: decode MODRM_REG {
+ 0x0: INC(Eb);
+ 0x1: DEC(Eb);
+ default: UD2();
+ }
+ //0x7: group5();
+ 0x7: decode MODRM_REG {
+ 0x0: INC(Ev);
+ 0x1: DEC(Ev);
+ 0x2: CALL_NEAR(Ev);
+ 0x3: WarnUnimpl::call_far_Mp();
+ 0x4: JMP(Ev);
+ 0x5: WarnUnimpl::jmp_far_Mp();
+ 0x6: PUSH(Ev);
+ 0x7: UD2();
+ }
}
}
}
diff --git a/src/arch/x86/isa/insts/control_transfer/call.py b/src/arch/x86/isa/insts/control_transfer/call.py
index c40080d85..c5bb66e58 100644
--- a/src/arch/x86/isa/insts/control_transfer/call.py
+++ b/src/arch/x86/isa/insts/control_transfer/call.py
@@ -59,11 +59,46 @@ def macroop CALL_NEAR_I
# Make the default data size of calls 64 bits in 64 bit mode
.adjust_env oszIn64Override
- limm t2, imm
+ limm t1, imm
+ rdip t7
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wrip t7, t1
+};
+
+def macroop CALL_NEAR_R
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
rdip t1
subi rsp, rsp, dsz
st t1, ss, [0, t0, rsp]
- wrip t1, t2
+ wripi reg, 0
+};
+
+def macroop CALL_NEAR_M
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [scale, index, base], disp
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wripi t1, 0
+};
+
+def macroop CALL_NEAR_P
+{
+ # Make the default data size of calls 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ subi rsp, rsp, dsz
+ st t7, ss, [0, t0, rsp]
+ wripi t1, 0
};
'''
#let {{
diff --git a/src/arch/x86/isa/insts/control_transfer/jump.py b/src/arch/x86/isa/insts/control_transfer/jump.py
index 489eb9e39..158861a3d 100644
--- a/src/arch/x86/isa/insts/control_transfer/jump.py
+++ b/src/arch/x86/isa/insts/control_transfer/jump.py
@@ -235,4 +235,10 @@ def macroop JMP_M
wripi t1, 0
};
+def macroop JMP_P
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ wripi t1, 0
+};
'''
diff --git a/src/arch/x86/isa/insts/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
index 585437b8c..c381dc4f4 100644
--- a/src/arch/x86/isa/insts/data_transfer/stack_operations.py
+++ b/src/arch/x86/isa/insts/data_transfer/stack_operations.py
@@ -69,6 +69,25 @@ def macroop PUSH_R {
subi rsp, rsp, dsz
st reg, ss, [0, t0, rsp]
};
+
+def macroop PUSH_M {
+ # Make the default data size of pops 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ ld t1, ds, [scale, index, base], disp
+ subi rsp, rsp, dsz
+ st t1, ss, [0, t0, rsp]
+};
+
+def macroop PUSH_P {
+ # Make the default data size of pops 64 bits in 64 bit mode
+ .adjust_env oszIn64Override
+
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ subi rsp, rsp, dsz
+ st t1, ss, [0, t0, rsp]
+};
'''
#let {{
# class POPA(Inst):
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
index e3aaf0043..5330b1ac5 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/rotate.py
@@ -53,14 +53,50 @@
#
# Authors: Gabe Black
-microcode = ""
+microcode = '''
+def macroop ROL_R_I
+{
+ rol reg, reg, imm
+};
+
+def macroop ROL_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ rol t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROL_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ rol t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop ROR_R_I
+{
+ ror reg, reg, imm
+};
+
+def macroop ROR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ ror t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop ROR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ ror t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+'''
#let {{
# class RCL(Inst):
# "GenFault ${new UnimpInstFault}"
# class RCR(Inst):
# "GenFault ${new UnimpInstFault}"
-# class ROL(Inst):
-# "GenFault ${new UnimpInstFault}"
-# class ROR(Inst):
-# "GenFault ${new UnimpInstFault}"
#}};
diff --git a/src/arch/x86/isa/insts/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
index b1c86a921..5a04317d9 100644
--- a/src/arch/x86/isa/insts/rotate_and_shift/shift.py
+++ b/src/arch/x86/isa/insts/rotate_and_shift/shift.py
@@ -73,6 +73,46 @@ def macroop SAL_P_I
sll t1, t1, imm
st t1, ds, [0, t0, t7], disp
};
+
+def macroop SHR_R_I
+{
+ srl reg, reg, imm
+};
+
+def macroop SHR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ srl t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SHR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ srl t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
+
+def macroop SAR_R_I
+{
+ sra reg, reg, imm
+};
+
+def macroop SAR_M_I
+{
+ ld t1, ds, [scale, index, base], disp
+ sra t1, t1, imm
+ st t1, ds, [scale, index, base], disp
+};
+
+def macroop SAR_P_I
+{
+ rdip t7
+ ld t1, ds, [0, t0, t7], disp
+ sra t1, t1, imm
+ st t1, ds, [0, t0, t7], disp
+};
'''
#let {{
# class SAL(Inst):
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index d2002b4fb..1f4de5642 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -381,34 +381,6 @@ let {{
setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
flagCode = immFlagCode, condCheck = condCode, elseCode = elseCode);
- defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
- defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
- defineMicroRegOp('Adc', '''
- CCFlagBits flags = ccFlagBits;
- DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
- ''')
- defineMicroRegOp('Sbb', '''
- CCFlagBits flags = ccFlagBits;
- DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
- ''', True)
- defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
- defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
- defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
- # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
- defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
- defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
- elseCode='DestReg=DestReg;', cc=True)
-
- # Shift instructions
- defineMicroRegOp('Sll', '''
- uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
- DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
- ''')
- # There are special rules for the flag for a single bit shift
- defineMicroRegOp('Bll', '''
- DestReg = merge(DestReg, SrcReg1 << 1, dataSize);
- ''')
-
# This has it's own function because Wr ops have implicit destinations
def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
Name = mnemonic
@@ -445,8 +417,6 @@ let {{
setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode,
condCheck = checkCCFlagBits, elseCode = elseCode);
- defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
-
# This has it's own function because Rd ops don't always have two parameters
def defineMicroRegOpRd(mnemonic, code):
Name = mnemonic
@@ -462,8 +432,6 @@ let {{
setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
- defineMicroRegOpRd('Rdip', 'DestReg = RIP')
-
def defineMicroRegOpImm(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
@@ -478,6 +446,80 @@ let {{
setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code);
+ defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
+ defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
+ defineMicroRegOp('Adc', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 + op2 + flags.CF, dataSize);
+ ''')
+ defineMicroRegOp('Sbb', '''
+ CCFlagBits flags = ccFlagBits;
+ DestReg = merge(DestReg, SrcReg1 - op2 - flags.CF, dataSize);
+ ''', True)
+ defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
+ defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', True)
+ defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
+ # defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', True)
+ defineMicroRegOp('Mul1s', 'DestReg = merge(DestReg, DestReg * op2, dataSize)')
+ defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)',
+ elseCode='DestReg=DestReg;', cc=True)
+
+ # Shift instructions
+ defineMicroRegOp('Sll', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ DestReg = merge(DestReg, SrcReg1 << shiftAmt, dataSize);
+ ''')
+ defineMicroRegOp('Srl', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to mask them out
+ // to be sure they're zero.
+ uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) & logicalMask, dataSize);
+ ''')
+ defineMicroRegOp('Sra', '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ // Because what happens to the bits shift -in- on a right shift
+ // is not defined in the C/C++ standard, we have to sign extend
+ // them manually to be sure.
+ uint64_t arithMask =
+ -bits(op2, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, (SrcReg1 >> shiftAmt) | arithMask, dataSize);
+ ''')
+ defineMicroRegOp('Ror', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << (dataSize * 8 - shiftAmt);
+ uint64_t bottom = bits(SrcReg1, dataSize * 8, shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcr', '''
+ ''')
+ defineMicroRegOp('Rol', '''
+ uint8_t shiftAmt =
+ (op2 & ((dataSize == 8) ? mask(4) : mask(3)));
+ if(shiftAmt)
+ {
+ uint64_t top = SrcReg1 << shiftAmt;
+ uint64_t bottom =
+ bits(SrcReg1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
+ DestReg = merge(DestReg, top | bottom, dataSize);
+ }
+ else
+ DestReg = DestReg;
+ ''')
+ defineMicroRegOp('Rcl', '''
+ ''')
+
+ defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2', elseCode="RIP = RIP;")
+
+ defineMicroRegOpRd('Rdip', 'DestReg = RIP')
+
defineMicroRegOpImm('Sext', '''
IntReg val = SrcReg1;
int sign_bit = bits(val, imm8-1, imm8-1);