aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe')
-rw-r--r--lib/hipe/amd64/hipe_amd64_encode.erl6
-rw-r--r--lib/hipe/x86/hipe_x86_assemble.erl37
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