|
@@ -114,6 +114,8 @@ unit cgcpu;
|
|
|
|
|
|
procedure gen_multiply(list: TAsmList; op: topcg; size: TCgSize; src2, src1, dst: tregister; check_overflow: boolean; var ovloc: tlocation);
|
|
procedure gen_multiply(list: TAsmList; op: topcg; size: TCgSize; src2, src1, dst: tregister; check_overflow: boolean; var ovloc: tlocation);
|
|
|
|
|
|
|
|
+ private
|
|
|
|
+ procedure a_op_const_reg_reg_internal(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, srchi, dst, dsthi: tregister);
|
|
protected
|
|
protected
|
|
procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
|
|
procedure a_op_reg_reg_internal(list: TAsmList; Op: TOpCG; size: TCGSize; src, srchi, dst, dsthi: TRegister);
|
|
procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
|
|
procedure a_op_const_reg_internal(list : TAsmList; Op: TOpCG; size: TCGSize; a: tcgint; reg, reghi: TRegister);
|
|
@@ -123,6 +125,7 @@ unit cgcpu;
|
|
tcg64favr = class(tcg64f32)
|
|
tcg64favr = class(tcg64f32)
|
|
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
|
|
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
|
|
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
|
|
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
|
|
|
|
+ procedure a_op64_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; value: int64;src,dst: tregister64);override;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure create_codegen;
|
|
procedure create_codegen;
|
|
@@ -438,6 +441,12 @@ unit cgcpu;
|
|
|
|
|
|
|
|
|
|
procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
|
|
procedure tcgavr.a_op_const_reg_reg(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister);
|
|
|
|
+ begin
|
|
|
|
+ a_op_const_reg_reg_internal(list,op,size,a,src,NR_NO,dst,NR_NO);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ procedure tcgavr.a_op_const_reg_reg_internal(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src,srchi,dst,dsthi: tregister);
|
|
var
|
|
var
|
|
tmpSrc, tmpDst, countreg: TRegister;
|
|
tmpSrc, tmpDst, countreg: TRegister;
|
|
b, b2, i, j: byte;
|
|
b, b2, i, j: byte;
|
|
@@ -478,12 +487,12 @@ unit cgcpu;
|
|
for i:=0 to (tcgsize2size[size]-b-1) do
|
|
for i:=0 to (tcgsize2size[size]-b-1) do
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
a_load_reg_reg(list,OS_8,OS_8,
|
|
a_load_reg_reg(list,OS_8,OS_8,
|
|
- GetOffsetReg64(src,NR_NO,i),
|
|
|
|
- GetOffsetReg64(dst,NR_NO,i+b))
|
|
|
|
|
|
+ GetOffsetReg64(src,srchi,i),
|
|
|
|
+ GetOffsetReg64(dst,dsthi,i+b))
|
|
else
|
|
else
|
|
a_load_reg_reg(list,OS_8,OS_8,
|
|
a_load_reg_reg(list,OS_8,OS_8,
|
|
- GetOffsetReg64(src,NR_NO,i+b),
|
|
|
|
- GetOffsetReg64(dst,NR_NO,i));
|
|
|
|
|
|
+ GetOffsetReg64(src,srchi,i+b),
|
|
|
|
+ GetOffsetReg64(dst,dsthi,i));
|
|
|
|
|
|
{ remaining bit shifts }
|
|
{ remaining bit shifts }
|
|
if b2 > 0 then
|
|
if b2 > 0 then
|
|
@@ -503,17 +512,17 @@ unit cgcpu;
|
|
a_load_const_reg(list,OS_8,b2,countreg);
|
|
a_load_const_reg(list,OS_8,b2,countreg);
|
|
cg.a_label(list,l1);
|
|
cg.a_label(list,l1);
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
- list.concat(taicpu.op_reg(A_LSL,GetOffsetReg64(dst,NR_NO,b)))
|
|
|
|
|
|
+ list.concat(taicpu.op_reg(A_LSL,GetOffsetReg64(dst,dsthi,b)))
|
|
else
|
|
else
|
|
- list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-1-b)));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg(A_LSR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-1-b)));
|
|
|
|
|
|
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
|
|
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
|
|
begin
|
|
begin
|
|
for i:=2+b to tcgsize2size[size] do
|
|
for i:=2+b to tcgsize2size[size] do
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
- list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,NR_NO,i-1)))
|
|
|
|
|
|
+ list.concat(taicpu.op_reg(A_ROL,GetOffsetReg64(dst,dsthi,i-1)))
|
|
else
|
|
else
|
|
- list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-i)));
|
|
|
|
|
|
+ list.concat(taicpu.op_reg(A_ROR,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i)));
|
|
end;
|
|
end;
|
|
list.concat(taicpu.op_reg(A_DEC,countreg));
|
|
list.concat(taicpu.op_reg(A_DEC,countreg));
|
|
a_jmp_flags(list,F_NE,l1);
|
|
a_jmp_flags(list,F_NE,l1);
|
|
@@ -527,19 +536,19 @@ unit cgcpu;
|
|
begin
|
|
begin
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
list.concat(taicpu.op_reg(A_LSL,
|
|
list.concat(taicpu.op_reg(A_LSL,
|
|
- GetOffsetReg64(dst,NR_NO,b)))
|
|
|
|
|
|
+ GetOffsetReg64(dst,dsthi,b)))
|
|
else
|
|
else
|
|
list.concat(taicpu.op_reg(A_LSR,
|
|
list.concat(taicpu.op_reg(A_LSR,
|
|
- GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-b-1)));
|
|
|
|
|
|
+ GetOffsetReg64(dst,dsthi,tcgsize2size[size]-b-1)));
|
|
|
|
|
|
if not(size in [OS_8,OS_S8]) then
|
|
if not(size in [OS_8,OS_S8]) then
|
|
for i:=2 to tcgsize2size[size]-b do
|
|
for i:=2 to tcgsize2size[size]-b do
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
list.concat(taicpu.op_reg(A_ROL,
|
|
list.concat(taicpu.op_reg(A_ROL,
|
|
- GetOffsetReg64(dst,NR_NO,b+i-1)))
|
|
|
|
|
|
+ GetOffsetReg64(dst,dsthi,b+i-1)))
|
|
else
|
|
else
|
|
list.concat(taicpu.op_reg(A_ROR,
|
|
list.concat(taicpu.op_reg(A_ROR,
|
|
- GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-b-i)));
|
|
|
|
|
|
+ GetOffsetReg64(dst,dsthi,tcgsize2size[size]-b-i)));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -548,9 +557,9 @@ unit cgcpu;
|
|
Do last,then optimizer can optimize register moves }
|
|
Do last,then optimizer can optimize register moves }
|
|
for i:=1 to b do
|
|
for i:=1 to b do
|
|
if op=OP_SHL then
|
|
if op=OP_SHL then
|
|
- emit_mov(list,GetOffsetReg64(dst,NR_NO,i-1),NR_R1)
|
|
|
|
|
|
+ emit_mov(list,GetOffsetReg64(dst,dsthi,i-1),NR_R1)
|
|
else
|
|
else
|
|
- emit_mov(list,GetOffsetReg64(dst,NR_NO,tcgsize2size[size]-i),NR_R1);
|
|
|
|
|
|
+ emit_mov(list,GetOffsetReg64(dst,dsthi,tcgsize2size[size]-i),NR_R1);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
|
|
inherited a_op_const_reg_reg(list,op,size,a,src,dst);
|
|
@@ -2849,6 +2858,15 @@ unit cgcpu;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
|
|
+ procedure tcg64favr.a_op64_const_reg_reg(list: TAsmList; op: TOpCg;size: tcgsize;value: int64;src,dst : tregister64);
|
|
|
|
+ begin
|
|
|
|
+ if op in [OP_SHL,OP_SHR] then
|
|
|
|
+ tcgavr(cg).a_op_const_reg_reg_internal(list,Op,size,value,src.reglo,src.reghi,dst.reglo,dst.reghi)
|
|
|
|
+ else
|
|
|
|
+ Inherited a_op64_const_reg_reg(list,op,size,value,src,dst);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+
|
|
procedure create_codegen;
|
|
procedure create_codegen;
|
|
begin
|
|
begin
|
|
cg:=tcgavr.create;
|
|
cg:=tcgavr.create;
|