diff options
Diffstat (limited to 'src')
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; |