diff options
-rw-r--r-- | lib/hipe/amd64/hipe_amd64_encode.erl | 6 | ||||
-rw-r--r-- | lib/hipe/x86/hipe_x86_assemble.erl | 37 |
2 files changed, 28 insertions, 15 deletions
diff --git a/lib/hipe/amd64/hipe_amd64_encode.erl b/lib/hipe/amd64/hipe_amd64_encode.erl index c41eaa3c6a..16bd705055 100644 --- a/lib/hipe/amd64/hipe_amd64_encode.erl +++ b/lib/hipe/amd64/hipe_amd64_encode.erl @@ -828,12 +828,16 @@ test_encode(Opnds) -> [?PFX_OPND_16BITS, 16#A9 | le16(Imm16, [])]; {eax, {imm32,Imm32}} -> [16#A9 | le32(Imm32, [])]; + {rax, {imm32,Imm32}} -> + [rex([{w,1}]), 16#A9 | le32(Imm32, [])]; {{rm8,RM8}, {imm8,Imm8}} -> [rex([{r8,RM8}]), 16#F6 | encode_rm(RM8, 2#000, [Imm8])]; {{rm16,RM16}, {imm16,Imm16}} -> [?PFX_OPND_16BITS, 16#F7 | encode_rm(RM16, 2#000, le16(Imm16, []))]; {{rm32,RM32}, {imm32,Imm32}} -> [16#F7 | encode_rm(RM32, 2#000, le32(Imm32, []))]; + {{rm64,RM64}, {imm32,Imm32}} -> + [rex([{w,1}]), 16#F7 | encode_rm(RM64, 2#000, le32(Imm32, []))]; {{rm32,RM32}, {reg32,Reg32}} -> [16#85 | encode_rm(RM32, Reg32, [])]; {{rm64,RM64}, {reg64,Reg64}} -> @@ -1478,10 +1482,12 @@ dotest1(OS) -> t(OS,'test',{al,Imm8}), t(OS,'test',{ax,Imm16}), t(OS,'test',{eax,Imm32}), + t(OS,'test',{rax,Imm32}), t(OS,'test',{RM8,Imm8}), t(OS,'test',{RM8REX,Imm8}), t(OS,'test',{RM16,Imm16}), t(OS,'test',{RM32,Imm32}), + t(OS,'test',{RM64,Imm32}), t(OS,'test',{RM32,Reg32}), t(OS,'test',{RM64,Reg64}), t(OS,'xor',{eax,Imm32}), diff --git a/lib/hipe/x86/hipe_x86_assemble.erl b/lib/hipe/x86/hipe_x86_assemble.erl index 4986933f50..e692ff0ebb 100644 --- a/lib/hipe/x86/hipe_x86_assemble.erl +++ b/lib/hipe/x86/hipe_x86_assemble.erl @@ -888,22 +888,29 @@ resolve_alu_args(Src, Dst, Context) -> %%% test resolve_test_args(Src, Dst, Context) -> case Src of - #x86_imm{} -> - Imm = translate_imm(Src, Context, false), - case Imm of - {imm8,_} -> - case Dst of - #x86_temp{reg=0} -> {al, Imm}; - #x86_temp{} -> resolve_test_imm8_reg(Imm, Dst); - #x86_mem{} -> {mem_to_rm8(Dst), Imm} - end; - {imm32,_} -> - {case Dst of - #x86_temp{reg=0} -> eax; - #x86_temp{} -> temp_to_rm32(Dst); - #x86_mem{} -> mem_to_rm32(Dst) - end, Imm} + %% Since we're using an 8-bit instruction, the immediate is not sign + %% extended. Thus, we can use immediates up to 255. + #x86_imm{value=ImmVal} + when is_integer(ImmVal), ImmVal >= 0, ImmVal =< 255 -> + Imm = {imm8, ImmVal}, + case Dst of + #x86_temp{reg=0} -> {al, Imm}; + #x86_temp{} -> resolve_test_imm8_reg(Imm, Dst); + #x86_mem{} -> {mem_to_rm8(Dst), Imm} end; + #x86_imm{value=ImmVal} when is_integer(ImmVal), ImmVal >= 0 -> + {case Dst of + #x86_temp{reg=0} -> eax; + #x86_temp{} -> temp_to_rm32(Dst); + #x86_mem{} -> mem_to_rm32(Dst) + end, {imm32, ImmVal}}; + #x86_imm{} -> % Negative ImmVal; use word-sized instr, imm32 + {_, ImmVal} = translate_imm(Src, Context, false), + {case Dst of + #x86_temp{reg=0} -> ?EAX; + #x86_temp{} -> temp_to_rmArch(Dst); + #x86_mem{} -> mem_to_rmArch(Dst) + end, {imm32, ImmVal}}; #x86_temp{} -> NewDst = case Dst of |