+ implemented OP_SHR/OP_SHL/OP_SAR support in tcg64f386.a_op64_reg_reg

git-svn-id: trunk@35831 -
This commit is contained in:
nickysn 2017-04-18 12:24:46 +00:00
parent 7e8c89435f
commit 10d7603dce

View File

@ -704,6 +704,7 @@ unit cgcpu;
procedure tcg64f386.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
var
op1,op2 : TAsmOp;
l1, l2: TAsmLabel;
begin
case op of
OP_NEG :
@ -725,6 +726,58 @@ unit cgcpu;
list.concat(taicpu.op_reg(A_NOT,S_L,regdst.reglo));
exit;
end;
OP_SHR,OP_SHL,OP_SAR:
begin
{ load right operators in a register }
cg.getcpuregister(list,NR_ECX);
cg.a_load_reg_reg(list,OS_32,OS_32,regsrc.reglo,NR_ECX);
{ the damned shift instructions work only til a count of 32 }
{ so we've to do some tricks here }
current_asmdata.getjumplabel(l1);
current_asmdata.getjumplabel(l2);
list.Concat(taicpu.op_const_reg(A_TEST,S_L,32,NR_ECX));
cg.a_jmp_flags(list,F_E,l1);
list.Concat(taicpu.op_const_reg(A_SUB,S_L,32,NR_ECX));
case op of
OP_SHL:
begin
list.Concat(taicpu.op_reg_reg(A_SHL,S_L,NR_CL,regdst.reglo));
cg.a_load_reg_reg(list,OS_32,OS_32,regdst.reglo,regdst.reghi);
list.Concat(taicpu.op_reg_reg(A_XOR,S_L,regdst.reglo,regdst.reglo));
cg.a_jmp_always(list,l2);
cg.a_label(list,l1);
list.Concat(taicpu.op_reg_reg_reg(A_SHLD,S_L,NR_CL,regdst.reglo,regdst.reghi));
list.Concat(taicpu.op_reg_reg(A_SHL,S_L,NR_CL,regdst.reglo));
end;
OP_SHR:
begin
list.Concat(taicpu.op_reg_reg(A_SHR,S_L,NR_CL,regdst.reghi));
cg.a_load_reg_reg(list,OS_32,OS_32,regdst.reghi,regdst.reglo);
list.Concat(taicpu.op_reg_reg(A_XOR,S_L,regdst.reghi,regdst.reghi));
cg.a_jmp_always(list,l2);
cg.a_label(list,l1);
list.Concat(taicpu.op_reg_reg_reg(A_SHRD,S_L,NR_CL,regdst.reghi,regdst.reglo));
list.Concat(taicpu.op_reg_reg(A_SHR,S_L,NR_CL,regdst.reghi));
end;
OP_SAR:
begin
cg.a_load_reg_reg(list,OS_32,OS_32,regdst.reghi,regdst.reglo);
list.Concat(taicpu.op_reg_reg(A_SAR,S_L,NR_CL,regdst.reglo));
list.Concat(taicpu.op_const_reg(A_SAR,S_L,31,regdst.reghi));
cg.a_jmp_always(list,l2);
cg.a_label(list,l1);
list.Concat(taicpu.op_reg_reg_reg(A_SHRD,S_L,NR_CL,regdst.reghi,regdst.reglo));
list.Concat(taicpu.op_reg_reg(A_SAR,S_L,NR_CL,regdst.reghi));
end;
else
internalerror(2017041801);
end;
cg.a_label(list,l2);
cg.ungetcpuregister(list,NR_ECX);
exit;
end;
end;
get_64bit_ops(op,op1,op2);
if op in [OP_ADD,OP_SUB] then