summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/x86/isa/decoder/locked_opcodes.isa3
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa2
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa11
-rw-r--r--src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py44
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py20
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/conditional_move.py52
-rw-r--r--src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py25
-rw-r--r--src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py93
-rw-r--r--src/arch/x86/isa/insts/general_purpose/semaphores.py94
-rw-r--r--src/arch/x86/isa/insts/general_purpose/string/scan_string.py6
-rw-r--r--src/arch/x86/isa/microops/regop.isa103
-rw-r--r--src/arch/x86/isa/operands.isa1
-rw-r--r--src/arch/x86/x86_traits.hh3
13 files changed, 377 insertions, 80 deletions
diff --git a/src/arch/x86/isa/decoder/locked_opcodes.isa b/src/arch/x86/isa/decoder/locked_opcodes.isa
index f38f2abb8..14d5e58a3 100644
--- a/src/arch/x86/isa/decoder/locked_opcodes.isa
+++ b/src/arch/x86/isa/decoder/locked_opcodes.isa
@@ -160,7 +160,8 @@
0x1: XADD_LOCKED(Mv,Gv);
//0x7: group9();
0x7: decode MODRM_REG {
- 0x1: WarnUnimpl::cmpxchg_Mq_LOCKED();
+ //Also CMPXCHG16B
+ 0x1: CMPXCHG8B_LOCKED(Mdp);
}
}
}
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index f365ed4b0..d6cfdc593 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -544,7 +544,7 @@
0x5: IMUL_B(Eb);
//This should be Eb, but it access the entire word value ax.
0x6: DIV_B(Ew);
- 0x7: IDIV(Eb);
+ 0x7: IDIV_B(Eb);
}
//0x7: group3_Ev();
0x7: decode MODRM_REG {
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index c344ee550..55056da81 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -820,8 +820,8 @@
Rdx = result.rdx;
}});
0x3: Inst::BT(Ev,Gv);
- 0x4: shld_Ev_Gv_Ib();
- 0x5: shld_Ev_Gv_rCl();
+ 0x4: Inst::SHLD(Ev,Gv,Ib);
+ 0x5: Inst::SHLD(Ev,Gv);
0x6: xbts_and_cmpxchg();
0x7: ibts_and_cmpxchg();
}
@@ -831,7 +831,7 @@
0x2: rsm_smm();
0x3: Inst::BTS(Ev,Gv);
0x4: Inst::SHRD(Ev,Gv,Ib);
- 0x5: shrd_Ev_Gv_rCl();
+ 0x5: Inst::SHRD(Ev,Gv);
//0x6: group16();
0x6: decode MODRM_REG {
0x0: fxsave();
@@ -898,7 +898,8 @@
0x1: Inst::XADD(Ev,Gv);
//0x7: group9();
0x7: decode MODRM_REG {
- 0x1: cmpxchg_Mq();
+ //Also CMPXCHG16B
+ 0x1: Inst::CMPXCHG8B(Mdp);
0x6: decode LEGACY_OP {
0x1: vmclear_Mq();
default: decode LEGACY_REP {
@@ -1067,7 +1068,7 @@
}
default: Inst::UD2();
}
- 0x1E: decode OPCODE_OP_BOTTOM3 {
+ 0x1E: decode LEGACY_DECODEVAL {
// no prefix
0x0: decode OPCODE_OP_BOTTOM3 {
0x1: psllw_Pq_Qq();
diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
index dbc803350..47ad1d53c 100644
--- a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
+++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py
@@ -388,7 +388,6 @@ def macroop IDIV_B_R
sub t2, t2, t4
#Find the sign of the divisor
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, reg, 1, flags=(ECF,), dataSize=1
# Negate divisor
@@ -397,7 +396,6 @@ def macroop IDIV_B_R
mov t3, t3, reg, flags=(nCECF,), dataSize=1
#Find the sign of the dividend
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, ah, 1, flags=(ECF,), dataSize=1
# Put the dividend's absolute value into t1 and t2
@@ -440,7 +438,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,), dataSize=1
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,), dataSize=1
+ slli t0, reg, 1, flags=(ECF,), dataSize=1
# Negate the (possibly already negated) quotient
sub t4, t0, t5, dataSize=1
@@ -458,19 +456,17 @@ def macroop IDIV_B_M
sub t2, t0, ah, dataSize=1
sub t2, t2, t4
- ld t3, seg, sib, disp
+ ld t8, seg, sib, disp
#Find the sign of the divisor
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, t3, 1, flags=(ECF,), dataSize=1
# Negate divisor
- sub t4, t0, t3, dataSize=1
+ sub t3, t0, t8, dataSize=1
# Put the divisor's absolute value into t3
- mov t3, t3, t4, flags=(CECF,), dataSize=1
+ mov t3, t3, t8, flags=(nCECF,), dataSize=1
#Find the sign of the dividend
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, ah, 1, flags=(ECF,), dataSize=1
# Put the dividend's absolute value into t1 and t2
@@ -513,7 +509,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,), dataSize=1
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,), dataSize=1
+ slli t0, t8, 1, flags=(ECF,), dataSize=1
# Negate the (possibly already negated) quotient
sub t4, t0, t5, dataSize=1
@@ -532,19 +528,17 @@ def macroop IDIV_B_P
sub t2, t2, t4
rdip t7
- ld t3, seg, riprel, disp
+ ld t8, seg, riprel, disp
#Find the sign of the divisor
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, t3, 1, flags=(ECF,), dataSize=1
# Negate divisor
- sub t4, t0, t3, dataSize=1
+ sub t3, t0, t8, dataSize=1
# Put the divisor's absolute value into t3
- mov t3, t3, t4, flags=(CECF,), dataSize=1
+ mov t3, t3, t8, flags=(nCECF,), dataSize=1
#Find the sign of the dividend
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, ah, 1, flags=(ECF,), dataSize=1
# Put the dividend's absolute value into t1 and t2
@@ -587,7 +581,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,), dataSize=1
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,), dataSize=1
+ slli t0, t8, 1, flags=(ECF,), dataSize=1
# Negate the (possibly already negated) quotient
sub t4, t0, t5, dataSize=1
@@ -610,7 +604,6 @@ def macroop IDIV_R
sub t2, t2, t4
#Find the sign of the divisor
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, reg, 1, flags=(ECF,)
# Negate divisor
@@ -619,7 +612,6 @@ def macroop IDIV_R
mov t3, t3, reg, flags=(nCECF,)
#Find the sign of the dividend
- #FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, rdx, 1, flags=(ECF,)
# Put the dividend's absolute value into t1 and t2
@@ -664,7 +656,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,)
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,)
+ slli t0, reg, 1, flags=(ECF,)
# Negate the (possibly already negated) quotient
sub t4, t0, t5
@@ -682,16 +674,16 @@ def macroop IDIV_M
sub t2, t0, rdx
sub t2, t2, t4
- ld t3, seg, sib, disp
+ ld t8, seg, sib, disp
#Find the sign of the divisor
#FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, t3, 1, flags=(ECF,)
# Negate divisor
- sub t4, t0, t3
+ sub t3, t0, t8
# Put the divisor's absolute value into t3
- mov t3, t3, t4, flags=(CECF,)
+ mov t3, t3, t8, flags=(nCECF,)
#Find the sign of the dividend
#FIXME!!! This depends on shifts setting the carry flag correctly.
@@ -739,7 +731,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,)
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,)
+ slli t0, t8, 1, flags=(ECF,)
# Negate the (possibly already negated) quotient
sub t4, t0, t5
@@ -758,16 +750,16 @@ def macroop IDIV_P
sub t2, t2, t4
rdip t7
- ld t3, seg, riprel, disp
+ ld t8, seg, riprel, disp
#Find the sign of the divisor
#FIXME!!! This depends on shifts setting the carry flag correctly.
slli t0, t3, 1, flags=(ECF,)
# Negate divisor
- sub t4, t0, t3
+ sub t3, t0, t8
# Put the divisor's absolute value into t3
- mov t3, t3, t4, flags=(CECF,)
+ mov t3, t3, t4, flags=(nCECF,)
#Find the sign of the dividend
#FIXME!!! This depends on shifts setting the carry flag correctly.
@@ -815,7 +807,7 @@ divLoopTop:
mov t5, t5, t4, (CECF,)
# Check the sign of the divisor
- slli t0, t3, 1, flags=(ECF,)
+ slli t0, t8, 1, flags=(ECF,)
# Negate the (possibly already negated) quotient
sub t4, t0, t5
diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
index ac2343462..f6aac1761 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py
@@ -64,15 +64,15 @@ def macroop BSWAP_D_R
def macroop BSWAP_Q_R
{
roli reg, reg, 8, dataSize=2
- roli reg, reg, 16, dataSize=4
- roli reg, reg, 8, dataSize=2
- roli reg, reg, 32, dataSize=8
- roli reg, reg, 8, dataSize=2
- roli reg, reg, 16, dataSize=4
- roli reg, reg, 8, dataSize=2
+ roli t1, reg, 16, dataSize=4
+ # Top 4 bytes of t1 are now zero
+ roli t1, t1, 8, dataSize=2
+ roli t1, t1, 32, dataSize=8
+ srli t2, reg, 32, dataSize=8
+ roli t2, t2, 8, dataSize=2
+ roli t2, t2, 16, dataSize=4
+ # Top 4 bytes of t2 are now zero
+ roli t2, t2, 8, dataSize=2
+ or reg, t1, t2, dataSize=8
};
'''
-#let {{
-# class BSWAP(Inst):
-# "GenFault ${new UnimpInstFault}"
-#}};
diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/conditional_move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/conditional_move.py
index 1a60c5b61..264bbe370 100644
--- a/src/arch/x86/isa/insts/general_purpose/data_transfer/conditional_move.py
+++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/conditional_move.py
@@ -56,12 +56,14 @@
microcode = '''
def macroop CMOVZ_R_R
{
+ mov reg, reg, reg, flags=(nCZF,)
mov reg, reg, regm, flags=(CZF,)
};
def macroop CMOVZ_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCZF,)
mov reg, reg, t1, flags=(CZF,)
};
@@ -69,17 +71,20 @@ def macroop CMOVZ_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCZF,)
mov reg, reg, t1, flags=(CZF,)
};
def macroop CMOVNZ_R_R
{
+ mov reg, reg, reg, flags=(CZF,)
mov reg, reg, regm, flags=(nCZF,)
};
def macroop CMOVNZ_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CZF,)
mov reg, reg, t1, flags=(nCZF,)
};
@@ -87,17 +92,20 @@ def macroop CMOVNZ_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CZF,)
mov reg, reg, t1, flags=(nCZF,)
};
def macroop CMOVB_R_R
{
+ mov reg, reg, reg, flags=(nCCF,)
mov reg, reg, regm, flags=(CCF,)
};
def macroop CMOVB_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCCF,)
mov reg, reg, t1, flags=(CCF,)
};
@@ -105,17 +113,20 @@ def macroop CMOVB_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCCF,)
mov reg, reg, t1, flags=(CCF,)
};
def macroop CMOVNB_R_R
{
+ mov reg, reg, reg, flags=(CCF,)
mov reg, reg, regm, flags=(nCCF,)
};
def macroop CMOVNB_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CCF,)
mov reg, reg, t1, flags=(nCCF,)
};
@@ -123,17 +134,20 @@ def macroop CMOVNB_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CCF,)
mov reg, reg, t1, flags=(nCCF,)
};
def macroop CMOVBE_R_R
{
+ mov reg, reg, reg, flags=(nCCvZF,)
mov reg, reg, regm, flags=(CCvZF,)
};
def macroop CMOVBE_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCCvZF,)
mov reg, reg, t1, flags=(CCvZF,)
};
@@ -141,17 +155,20 @@ def macroop CMOVBE_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCCvZF,)
mov reg, reg, t1, flags=(CCvZF,)
};
def macroop CMOVNBE_R_R
{
+ mov reg, reg, reg, flags=(CCvZF,)
mov reg, reg, regm, flags=(nCCvZF,)
};
def macroop CMOVNBE_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CCvZF,)
mov reg, reg, t1, flags=(nCCvZF,)
};
@@ -159,17 +176,20 @@ def macroop CMOVNBE_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CCvZF,)
mov reg, reg, t1, flags=(nCCvZF,)
};
def macroop CMOVS_R_R
{
+ mov reg, reg, reg, flags=(nCSF,)
mov reg, reg, regm, flags=(CSF,)
};
def macroop CMOVS_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCSF,)
mov reg, reg, t1, flags=(CSF,)
};
@@ -177,17 +197,20 @@ def macroop CMOVS_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCSF,)
mov reg, reg, t1, flags=(CSF,)
};
def macroop CMOVNS_R_R
{
+ mov reg, reg, reg, flags=(CSF,)
mov reg, reg, regm, flags=(nCSF,)
};
def macroop CMOVNS_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CSF,)
mov reg, reg, t1, flags=(nCSF,)
};
@@ -195,17 +218,20 @@ def macroop CMOVNS_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CSF,)
mov reg, reg, t1, flags=(nCSF,)
};
def macroop CMOVP_R_R
{
+ mov reg, reg, reg, flags=(nCPF,)
mov reg, reg, regm, flags=(CPF,)
};
def macroop CMOVP_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCPF,)
mov reg, reg, t1, flags=(CPF,)
};
@@ -213,35 +239,41 @@ def macroop CMOVP_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCPF,)
mov reg, reg, t1, flags=(CPF,)
};
def macroop CMOVNP_R_R
{
+ mov reg, reg, reg, flags=(CPF,)
mov reg, reg, regm, flags=(nCPF,)
};
def macroop CMOVNP_R_M
{
ld t1, seg, sib, disp
- mov reg, reg, regm, flags=(nCPF,)
+ mov reg, reg, reg, flags=(CPF,)
+ mov reg, reg, t1, flags=(nCPF,)
};
def macroop CMOVNP_R_P
{
rdip t7
ld t1, seg, riprel, disp
- mov reg, reg, regm, flags=(nCPF,)
+ mov reg, reg, reg, flags=(CPF,)
+ mov reg, reg, t1, flags=(nCPF,)
};
def macroop CMOVL_R_R
{
+ mov reg, reg, reg, flags=(nCSxOF,)
mov reg, reg, regm, flags=(CSxOF,)
};
def macroop CMOVL_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCSxOF,)
mov reg, reg, t1, flags=(CSxOF,)
};
@@ -249,17 +281,20 @@ def macroop CMOVL_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCSxOF,)
mov reg, reg, t1, flags=(CSxOF,)
};
def macroop CMOVNL_R_R
{
+ mov reg, reg, reg, flags=(CSxOF,)
mov reg, reg, regm, flags=(nCSxOF,)
};
def macroop CMOVNL_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CSxOF,)
mov reg, reg, t1, flags=(nCSxOF,)
};
@@ -267,17 +302,20 @@ def macroop CMOVNL_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CSxOF,)
mov reg, reg, t1, flags=(nCSxOF,)
};
def macroop CMOVLE_R_R
{
+ mov reg, reg, reg, flags=(nCSxOvZF,)
mov reg, reg, regm, flags=(CSxOvZF,)
};
def macroop CMOVLE_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCSxOvZF,)
mov reg, reg, t1, flags=(CSxOvZF,)
};
@@ -285,17 +323,20 @@ def macroop CMOVLE_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCSxOvZF,)
mov reg, reg, t1, flags=(CSxOvZF,)
};
def macroop CMOVNLE_R_R
{
+ mov reg, reg, reg, flags=(CSxOvZF,)
mov reg, reg, regm, flags=(nCSxOvZF,)
};
def macroop CMOVNLE_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(CSxOvZF,)
mov reg, reg, t1, flags=(nCSxOvZF,)
};
@@ -303,17 +344,20 @@ def macroop CMOVNLE_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(CSxOvZF,)
mov reg, reg, t1, flags=(nCSxOvZF,)
};
def macroop CMOVO_R_R
{
+ mov reg, reg, reg, flags=(nCOF,)
mov reg, reg, regm, flags=(COF,)
};
def macroop CMOVO_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(nCOF,)
mov reg, reg, t1, flags=(COF,)
};
@@ -321,17 +365,20 @@ def macroop CMOVO_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(nCOF,)
mov reg, reg, t1, flags=(COF,)
};
def macroop CMOVNO_R_R
{
+ mov reg, reg, reg, flags=(COF,)
mov reg, reg, regm, flags=(nCOF,)
};
def macroop CMOVNO_R_M
{
ld t1, seg, sib, disp
+ mov reg, reg, reg, flags=(COF,)
mov reg, reg, t1, flags=(nCOF,)
};
@@ -339,6 +386,7 @@ def macroop CMOVNO_R_P
{
rdip t7
ld t1, seg, riprel, disp
+ mov reg, reg, reg, flags=(COF,)
mov reg, reg, t1, flags=(nCOF,)
};
'''
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 f4c8a4663..6b18caef0 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
@@ -150,28 +150,29 @@ def macroop LEAVE {
# Make the default data size of pops 64 bits in 64 bit mode
.adjust_env oszIn64Override
- mov t1, t1, rbp, dataSize=asz
+ mov t1, t1, rbp, dataSize=ssz
ld rbp, ss, [1, t0, t1], dataSize=ssz
- mov rsp, rsp, t1, dataSize=asz
- addi rsp, rsp, ssz, dataSize=asz
+ mov rsp, rsp, t1, dataSize=ssz
+ addi rsp, rsp, ssz, dataSize=ssz
};
def macroop ENTER_I_I {
+ .adjust_env oszIn64Override
# This needs to check all the addresses it writes to before it actually
# writes any values.
# Pull the different components out of the immediate
- limm t1, imm
+ limm t1, imm, dataSize=8
zexti t2, t1, 15, dataSize=8
- srli t1, t1, 16
+ srli t1, t1, 16, dataSize=8
zexti t1, t1, 5, dataSize=8
# t1 is now the masked nesting level, and t2 is the amount of storage.
# Push rbp.
- stupd rbp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz
+ stupd rbp, ss, [1, t0, rsp], "-env.dataSize"
# Save the stack pointer for later
- mov t6, t6, rsp, dataSize=asz
+ mov t6, t6, rsp
# If the nesting level is zero, skip all this stuff.
sub t0, t1, t0, flags=(EZF,), dataSize=2
@@ -183,8 +184,8 @@ def macroop ENTER_I_I {
limm t4, "ULL(-1)", dataSize=8
topOfLoop:
- ld t5, ss, [ssz, t4, rbp], dataSize=ssz
- stupd t5, ss, [1, t0, rsp], "-env.stackSize"
+ ld t5, ss, [dsz, t4, rbp]
+ stupd t5, ss, [1, t0, rsp], "-env.dataSize"
# If we're not done yet, loop
subi t4, t4, 1, dataSize=8
@@ -193,10 +194,10 @@ topOfLoop:
bottomOfLoop:
# Push the old rbp onto the stack
- stupd t6, ss, [1, t0, rsp], "-env.stackSize"
+ stupd t6, ss, [1, t0, rsp], "-env.dataSize"
skipLoop:
- sub rsp, rsp, t2, dataSize=asz
- mov rbp, rbp, t6, dataSize=asz
+ sub rsp, rsp, t2, dataSize=ssz
+ mov rbp, rbp, t6
};
'''
diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
index caaeca974..092fb4213 100644
--- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
+++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py
@@ -114,6 +114,52 @@ def macroop SAL_P_R
st t1, seg, riprel, disp
};
+def macroop SHLD_R_R
+{
+ mdbi regm, 0
+ sld reg, reg, rcx, flags=(CF,OF,SF,ZF,PF)
+};
+
+def macroop SHLD_M_R
+{
+ ldst t1, seg, sib, disp
+ mdbi reg, 0
+ sld t1, t1, rcx, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, sib, disp
+};
+
+def macroop SHLD_P_R
+{
+ rdip t7
+ ldst t1, seg, riprel, disp
+ mdbi reg, 0
+ sld t1, t1, rcx, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, riprel, disp
+};
+
+def macroop SHLD_R_R_I
+{
+ mdbi regm, 0
+ sldi reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
+};
+
+def macroop SHLD_M_R_I
+{
+ ldst t1, seg, sib, disp
+ mdbi reg, 0
+ sldi t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, sib, disp
+};
+
+def macroop SHLD_P_R_I
+{
+ rdip t7
+ ldst t1, seg, riprel, disp
+ mdbi reg, 0
+ sldi t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, riprel, disp
+};
+
def macroop SHR_R_I
{
srli reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
@@ -174,38 +220,49 @@ def macroop SHR_P_R
st t1, seg, riprel, disp
};
-# SHRD will not set OF correctly when the shift count is 1.
+def macroop SHRD_R_R
+{
+ mdbi regm, 0
+ srd reg, reg, rcx, flags=(CF,OF,SF,ZF,PF)
+};
+
+def macroop SHRD_M_R
+{
+ ldst t1, seg, sib, disp
+ mdbi reg, 0
+ srd t1, t1, rcx, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, sib, disp
+};
+
+def macroop SHRD_P_R
+{
+ rdip t7
+ ldst t1, seg, riprel, disp
+ mdbi reg, 0
+ srd t1, t1, rcx, flags=(CF,OF,SF,ZF,PF)
+ st t1, seg, riprel, disp
+};
+
def macroop SHRD_R_R_I
{
- srli t1, reg, imm, flags=(CF,)
- rori t2, regm, imm
- srli t3, regm, imm
- xor t2, t2, t3
- or reg, t1, t2
+ mdbi regm, 0
+ srdi reg, reg, imm, flags=(CF,OF,SF,ZF,PF)
};
-# SHRD will not set OF correctly when the shift count is 1.
def macroop SHRD_M_R_I
{
ldst t1, seg, sib, disp
- srli t1, t1, imm, flags=(CF,)
- rori t2, reg, imm
- srli t3, reg, imm
- xor t2, t2, t3
- or t1, t1, t2
+ mdbi reg, 0
+ srdi t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, sib, disp
};
-# SHRD will not set OF correctly when the shift count is 1.
def macroop SHRD_P_R_I
{
rdip t7
ldst t1, seg, riprel, disp
- srli t1, t1, imm, flags=(CF,)
- rori t2, reg, imm
- srli t3, reg, imm
- xor t2, t2, t3
- or t1, t1, t2
+ mdbi reg, 0
+ srdi t1, t1, imm, flags=(CF,OF,SF,ZF,PF)
st t1, seg, riprel, disp
};
diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py
index a7da0720e..2bdbd0ada 100644
--- a/src/arch/x86/isa/insts/general_purpose/semaphores.py
+++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py
@@ -98,6 +98,100 @@ def macroop CMPXCHG_LOCKED_P_R {
mov rax, rax, t1, flags=(nCZF,)
};
+def macroop CMPXCHG8B_M {
+ lea t1, seg, sib, disp, dataSize=asz
+ ldst t2, seg, [1, t0, t1], 0
+ ldst t3, seg, [1, t0, t1], dsz
+
+ sub t0, rax, t2, flags=(ZF,)
+ br label("doneComparing"), flags=(nCZF,)
+ sub t0, rdx, t3, flags=(ZF,)
+doneComparing:
+
+ # If they're equal, set t3:t2 to rbx:rcx to write to memory
+ mov t2, t2, rbx, flags=(CZF,)
+ mov t3, t3, rcx, flags=(CZF,)
+
+ # If they're not equal, set rdx:rax to the value from memory.
+ mov rax, rax, t2, flags=(nCZF,)
+ mov rdx, rdx, t3, flags=(nCZF,)
+
+ # Write to memory
+ st t3, seg, [1, t0, t1], dsz
+ st t2, seg, [1, t0, t1], 0
+};
+
+def macroop CMPXCHG8B_P {
+ rdip t7
+ lea t1, seg, riprel, disp, dataSize=asz
+ ldst t2, seg, [1, t0, t1], 0
+ ldst t3, seg, [1, t0, t1], dsz
+
+ sub t0, rax, t2, flags=(ZF,)
+ br label("doneComparing"), flags=(nCZF,)
+ sub t0, rdx, t3, flags=(ZF,)
+doneComparing:
+
+ # If they're equal, set t3:t2 to rbx:rcx to write to memory
+ mov t2, t2, rbx, flags=(CZF,)
+ mov t3, t3, rcx, flags=(CZF,)
+
+ # If they're not equal, set rdx:rax to the value from memory.
+ mov rax, rax, t2, flags=(nCZF,)
+ mov rdx, rdx, t3, flags=(nCZF,)
+
+ # Write to memory
+ st t3, seg, [1, t0, t1], dsz
+ st t2, seg, [1, t0, t1], 0
+};
+
+def macroop CMPXCHG8B_LOCKED_M {
+ lea t1, seg, sib, disp, dataSize=asz
+ ldstl t2, seg, [1, t0, t1], 0
+ ldstl t3, seg, [1, t0, t1], dsz
+
+ sub t0, rax, t2, flags=(ZF,)
+ br label("doneComparing"), flags=(nCZF,)
+ sub t0, rdx, t3, flags=(ZF,)
+doneComparing:
+
+ # If they're equal, set t3:t2 to rbx:rcx to write to memory
+ mov t2, t2, rbx, flags=(CZF,)
+ mov t3, t3, rcx, flags=(CZF,)
+
+ # If they're not equal, set rdx:rax to the value from memory.
+ mov rax, rax, t2, flags=(nCZF,)
+ mov rdx, rdx, t3, flags=(nCZF,)
+
+ # Write to memory
+ stul t3, seg, [1, t0, t1], dsz
+ stul t2, seg, [1, t0, t1], 0
+};
+
+def macroop CMPXCHG8B_LOCKED_P {
+ rdip t7
+ lea t1, seg, riprel, disp, dataSize=asz
+ ldstl t2, seg, [1, t0, t1], 0
+ ldstl t3, seg, [1, t0, t1], dsz
+
+ sub t0, rax, t2, flags=(ZF,)
+ br label("doneComparing"), flags=(nCZF,)
+ sub t0, rdx, t3, flags=(ZF,)
+doneComparing:
+
+ # If they're equal, set t3:t2 to rbx:rcx to write to memory
+ mov t2, t2, rbx, flags=(CZF,)
+ mov t3, t3, rcx, flags=(CZF,)
+
+ # If they're not equal, set rdx:rax to the value from memory.
+ mov rax, rax, t2, flags=(nCZF,)
+ mov rdx, rdx, t3, flags=(nCZF,)
+
+ # Write to memory
+ stul t3, seg, [1, t0, t1], dsz
+ stul t2, seg, [1, t0, t1], 0
+};
+
def macroop XADD_M_R {
ldst t1, seg, sib, disp
add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF)
diff --git a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
index 5b0e74aad..5115fe8a2 100644
--- a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
+++ b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py
@@ -62,7 +62,7 @@ def macroop SCAS_M {
mov t2, t2, t3, flags=(nCEZF,), dataSize=asz
ld t1, es, [1, t0, rdi]
- sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF)
+ sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF)
add rdi, rdi, t2, dataSize=asz
};
@@ -84,7 +84,7 @@ def macroop SCAS_E_M {
topOfLoop:
ld t1, es, [1, t0, rdi]
- sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF)
+ sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF)
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t2, dataSize=asz
@@ -105,7 +105,7 @@ def macroop SCAS_N_M {
topOfLoop:
ld t1, es, [1, t0, rdi]
- sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF)
+ sub t0, rax, t1, flags=(OF, SF, ZF, AF, PF, CF)
subi rcx, rcx, 1, flags=(EZF,), dataSize=asz
add rdi, rdi, t2, dataSize=asz
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index dc6819886..a4cb6f4cc 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -639,7 +639,7 @@ let {{
class Mov(CondRegOp):
code = 'DestReg = merge(SrcReg1, op2, dataSize)'
- else_code = 'DestReg = merge(DestReg, DestReg, dataSize);'
+ else_code = 'DestReg = DestReg;'
# Shift instructions
@@ -884,6 +884,107 @@ let {{
}
'''
+ class Sld(RegOp):
+ code = '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
+ uint8_t dataBits = dataSize * 8;
+ uint8_t realShiftAmt = shiftAmt % (2 * dataBits);
+ uint64_t result;
+ if (realShiftAmt == 0) {
+ result = psrc1;
+ } else if (realShiftAmt < dataBits) {
+ result = (psrc1 << realShiftAmt) |
+ (DoubleBits >> (dataBits - realShiftAmt));
+ } else {
+ result = (DoubleBits << (realShiftAmt - dataBits)) |
+ (psrc1 >> (2 * dataBits - realShiftAmt));
+ }
+ DestReg = merge(DestReg, result, dataSize);
+ '''
+ flag_code = '''
+ // If the shift amount is zero, no flags should be modified.
+ if (shiftAmt) {
+ //Zero out any flags we might modify. This way we only have to
+ //worry about setting them.
+ ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ int CFBits = 0;
+ //Figure out if we -would- set the CF bits if requested.
+ if ((realShiftAmt == 0 &&
+ bits(DoubleBits, 0)) ||
+ (realShiftAmt <= dataBits &&
+ bits(SrcReg1, dataBits - realShiftAmt)) ||
+ (realShiftAmt > dataBits &&
+ bits(DoubleBits, 2 * dataBits - realShiftAmt))) {
+ CFBits = 1;
+ }
+ //If some combination of the CF bits need to be set, set them.
+ if ((ext & (CFBit | ECFBit)) && CFBits)
+ ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ //Figure out what the OF bit should be.
+ if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
+ bits(result, dataBits - 1)))
+ ccFlagBits = ccFlagBits | OFBit;
+ //Use the regular mechanisms to calculate the other flags.
+ ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
+ DestReg, psrc1, op2);
+ }
+ '''
+
+ class Srd(RegOp):
+ code = '''
+ uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
+ uint8_t dataBits = dataSize * 8;
+ uint8_t realShiftAmt = shiftAmt % (2 * dataBits);
+ uint64_t result;
+ if (realShiftAmt == 0) {
+ result = psrc1;
+ } else if (realShiftAmt < dataBits) {
+ // 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(dataBits - realShiftAmt);
+ result = ((psrc1 >> realShiftAmt) & logicalMask) |
+ (DoubleBits << (dataBits - realShiftAmt));
+ } else {
+ uint64_t logicalMask = mask(2 * dataBits - realShiftAmt);
+ result = ((DoubleBits >> (realShiftAmt - dataBits)) &
+ logicalMask) |
+ (psrc1 << (2 * dataBits - realShiftAmt));
+ }
+ DestReg = merge(DestReg, result, dataSize);
+ '''
+ flag_code = '''
+ // If the shift amount is zero, no flags should be modified.
+ if (shiftAmt) {
+ //Zero out any flags we might modify. This way we only have to
+ //worry about setting them.
+ ccFlagBits = ccFlagBits & ~(ext & (CFBit | ECFBit | OFBit));
+ int CFBits = 0;
+ //If some combination of the CF bits need to be set, set them.
+ if ((realShiftAmt == 0 &&
+ bits(DoubleBits, dataBits - 1)) ||
+ (realShiftAmt <= dataBits &&
+ bits(SrcReg1, realShiftAmt - 1)) ||
+ (realShiftAmt > dataBits &&
+ bits(DoubleBits, realShiftAmt - dataBits - 1))) {
+ CFBits = 1;
+ }
+ //If some combination of the CF bits need to be set, set them.
+ if ((ext & (CFBit | ECFBit)) && CFBits)
+ ccFlagBits = ccFlagBits | (ext & (CFBit | ECFBit));
+ //Figure out what the OF bit should be.
+ if ((ext & OFBit) && (bits(SrcReg1, dataBits - 1) ^
+ bits(result, dataBits - 1)))
+ ccFlagBits = ccFlagBits | OFBit;
+ //Use the regular mechanisms to calculate the other flags.
+ ccFlagBits = genFlags(ccFlagBits, ext & ~(CFBit | ECFBit | OFBit),
+ DestReg, psrc1, op2);
+ }
+ '''
+
+ class Mdb(WrRegOp):
+ code = 'DoubleBits = psrc1 ^ op2;'
+
class Wrip(WrRegOp, CondRegOp):
code = 'RIP = psrc1 + sop2 + CSBase'
else_code="RIP = RIP;"
diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa
index 5ea803bfc..135fc10df 100644
--- a/src/arch/x86/isa/operands.isa
+++ b/src/arch/x86/isa/operands.isa
@@ -127,6 +127,7 @@ def operands {{
'Quotient': impIntReg(2, 9),
'Remainder': impIntReg(3, 10),
'Divisor': impIntReg(4, 11),
+ 'DoubleBits': impIntReg(5, 11),
'Rax': intReg('(INTREG_RAX)', 12),
'Rbx': intReg('(INTREG_RBX)', 13),
'Rcx': intReg('(INTREG_RCX)', 14),
diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh
index 8b50bdf9b..a73aaef19 100644
--- a/src/arch/x86/x86_traits.hh
+++ b/src/arch/x86/x86_traits.hh
@@ -68,12 +68,13 @@ namespace X86ISA
const int NumPseudoIntRegs = 1;
//1. The condition code bits of the rflags register.
- const int NumImplicitIntRegs = 5;
+ const int NumImplicitIntRegs = 6;
//1. The lower part of the result of multiplication.
//2. The upper part of the result of multiplication.
//3. The quotient from division
//4. The remainder from division
//5. The divisor for division
+ //6. The register to use for shift doubles
const int NumMMXRegs = 8;
const int NumXMMRegs = 16;