(base.bxor_imm, 6)]: enc_i32_i64(inst, r.r_ib, 0x83, rrr=rrr) enc_i32_i64(inst, r.r_id, 0x81, rrr=rrr) # TODO: band_imm.i64 with an unsigned 32-bit immediate can be encoded as # band_imm.i32. Can even use the single-byte immediate for 0xffff_ffXX masks. # Immediate constants. X86_32.enc(base.iconst.i32, *r.pu_id(0xb8)) X86_64.enc(base.iconst.i32, *r.pu_id.rex(0xb8)) X86_64.enc(base.iconst.i32, *r.pu_id(0xb8)) # The 32-bit immediate movl also zero-extends to 64 bits. X86_64.enc(base.iconst.i64, *r.pu_id.rex(0xb8), instp=IsUnsignedInt(UnaryImm.imm, 32)) X86_64.enc(base.iconst.i64, *r.pu_id(0xb8), instp=IsUnsignedInt(UnaryImm.imm, 32)) # Sign-extended 32-bit immediate. X86_64.enc(base.iconst.i64, *r.u_id.rex(0xc7, rrr=0, w=1)) # Finally, the 0xb8 opcode takes an 8-byte immediate with a REX.W prefix. X86_64.enc(base.iconst.i64, *r.pu_iq.rex(0xb8, w=1)) # bool constants. enc_both(base.bconst.b1, r.pu_id_bool, 0xb8) # Shifts and rotates. # Note that the dynamic shift amount is only masked by 5 or 6 bits; the 8-bit # and 16-bit shifts would need explicit masking. for inst, rrr in [(base.rotl, 0), (base.rotr, 1), (base.ishl, 4),
(base.bxor_imm, 6)]: enc_i32_i64(inst, r.rib, 0x83, rrr=rrr) enc_i32_i64(inst, r.rid, 0x81, rrr=rrr) # TODO: band_imm.i64 with an unsigned 32-bit immediate can be encoded as # band_imm.i32. Can even use the single-byte immediate for 0xffff_ffXX masks. # Immediate constants. I32.enc(base.iconst.i32, *r.puid(0xb8)) I64.enc(base.iconst.i32, *r.puid.rex(0xb8)) I64.enc(base.iconst.i32, *r.puid(0xb8)) # The 32-bit immediate movl also zero-extends to 64 bits. I64.enc(base.iconst.i64, *r.puid.rex(0xb8), instp=IsUnsignedInt(UnaryImm.imm, 32)) I64.enc(base.iconst.i64, *r.puid(0xb8), instp=IsUnsignedInt(UnaryImm.imm, 32)) # Sign-extended 32-bit immediate. I64.enc(base.iconst.i64, *r.uid.rex(0xc7, rrr=0, w=1)) # Finally, the 0xb8 opcode takes an 8-byte immediate with a REX.W prefix. I64.enc(base.iconst.i64, *r.puiq.rex(0xb8, w=1)) # Shifts and rotates. # Note that the dynamic shift amount is only masked by 5 or 6 bits; the 8-bit # and 16-bit shifts would need explicit masking. for inst, rrr in [(base.rotl, 0), (base.rotr, 1), (base.ishl, 4), (base.ushr, 5), (base.sshr, 7)]: I32.enc(inst.i32.any, *r.rc(0xd3, rrr=rrr)) I64.enc(inst.i64.any, *r.rc.rex(0xd3, rrr=rrr, w=1)) I64.enc(inst.i32.any, *r.rc.rex(0xd3, rrr=rrr)) I64.enc(inst.i32.any, *r.rc(0xd3, rrr=rrr))