|
@@ -64,6 +64,8 @@ unit cgcpu;
|
|
|
procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
|
|
|
procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
|
|
|
procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
|
|
|
+ function a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
|
|
+ function a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
|
|
|
|
|
{ fpu move instructions }
|
|
|
procedure a_loadfpu_reg_reg(list: TAsmList; size: tcgsize; reg1, reg2: tregister); override;
|
|
@@ -100,7 +102,7 @@ unit cgcpu;
|
|
|
|
|
|
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
|
|
|
procedure fixref(list : TAsmList;var ref : treference);
|
|
|
- procedure handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
|
|
+ function handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
|
|
|
|
|
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
|
|
|
end;
|
|
@@ -577,11 +579,12 @@ unit cgcpu;
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference);
|
|
|
+ function tcgarm.handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
|
|
|
var
|
|
|
- tmpreg : tregister;
|
|
|
+ tmpreg,tmpreg2 : tregister;
|
|
|
tmpref : treference;
|
|
|
l : tasmlabel;
|
|
|
+ so : tshifterop;
|
|
|
begin
|
|
|
tmpreg:=NR_NO;
|
|
|
|
|
@@ -717,12 +720,16 @@ unit cgcpu;
|
|
|
end;
|
|
|
end;
|
|
|
list.concat(setoppostfix(taicpu.op_reg_ref(op,reg,ref),oppostfix));
|
|
|
+ Result := ref;
|
|
|
end;
|
|
|
|
|
|
|
|
|
procedure tcgarm.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
|
|
|
var
|
|
|
oppostfix:toppostfix;
|
|
|
+ usedtmpref,usedtmpref2: treference;
|
|
|
+ tmpreg,tmpreg2 : tregister;
|
|
|
+ so : tshifterop;
|
|
|
begin
|
|
|
case ToSize of
|
|
|
{ signed integer registers }
|
|
@@ -738,13 +745,49 @@ unit cgcpu;
|
|
|
else
|
|
|
InternalError(200308295);
|
|
|
end;
|
|
|
- handle_load_store(list,A_STR,oppostfix,reg,ref);
|
|
|
+ if ref.alignment<>0 then
|
|
|
+ begin
|
|
|
+ case FromSize of
|
|
|
+ OS_16,OS_S16:
|
|
|
+ begin
|
|
|
+ shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
+ usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,Ref);
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
|
|
|
+ a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
|
|
+ end;
|
|
|
+ OS_32,OS_S32:
|
|
|
+ begin
|
|
|
+ shifterop_reset(so);so.shiftmode:=SM_LSR;so.shiftimm:=8;
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
+
|
|
|
+ usedtmpref:=a_internal_load_reg_ref(list,OS_8,OS_8,reg,Ref);
|
|
|
+ list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,reg,so));
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
|
|
+ list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
|
|
+ list.concat(taicpu.op_reg_reg_shifterop(A_MOV,tmpreg,tmpreg,so));
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_reg_ref(list,OS_8,OS_8,tmpreg,usedtmpref);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ handle_load_store(list,A_STR,oppostfix,reg,ref);
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ handle_load_store(list,A_STR,oppostfix,reg,ref);
|
|
|
end;
|
|
|
|
|
|
|
|
|
procedure tcgarm.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
|
|
|
var
|
|
|
oppostfix:toppostfix;
|
|
|
+ usedtmpref,usedtmpref2: treference;
|
|
|
+ tmpreg,tmpreg2 : tregister;
|
|
|
+ so : tshifterop;
|
|
|
begin
|
|
|
case FromSize of
|
|
|
{ signed integer registers }
|
|
@@ -762,10 +805,90 @@ unit cgcpu;
|
|
|
else
|
|
|
InternalError(200308291);
|
|
|
end;
|
|
|
- handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
|
|
+ if Ref.alignment<>0 then
|
|
|
+ begin
|
|
|
+ case FromSize of
|
|
|
+ OS_16,OS_S16:
|
|
|
+ begin
|
|
|
+ shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
+ usedtmpref:=a_internal_load_ref_reg(list,OS_8,OS_8,Ref,tmpreg);
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
|
|
|
+ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,reg,tmpreg,so));
|
|
|
+ end;
|
|
|
+ OS_32,OS_S32:
|
|
|
+ begin
|
|
|
+ shifterop_reset(so);so.shiftmode:=SM_LSL;so.shiftimm:=8;
|
|
|
+ tmpreg:=getintregister(list,OS_INT);
|
|
|
+ tmpreg2:=getintregister(list,OS_INT);
|
|
|
+ usedtmpref:=a_internal_load_ref_reg(list,OS_8,OS_8,Ref,reg);
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg);
|
|
|
+ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg2,reg,tmpreg,so));
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,reg);
|
|
|
+ so.shiftimm:=16;
|
|
|
+ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,tmpreg,tmpreg2,reg,so));
|
|
|
+ inc(usedtmpref.offset);
|
|
|
+ a_internal_load_ref_reg(list,OS_8,OS_8,usedtmpref,tmpreg2);
|
|
|
+ so.shiftimm:=24;
|
|
|
+ list.concat(taicpu.op_reg_reg_reg_shifterop(A_ORR,reg,tmpreg,tmpreg2,so));
|
|
|
+ end
|
|
|
+ else
|
|
|
+ handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
|
|
+ end;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ function tcgarm.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
|
|
|
+ var
|
|
|
+ oppostfix:toppostfix;
|
|
|
+ begin
|
|
|
+ case ToSize of
|
|
|
+ { signed integer registers }
|
|
|
+ OS_8,
|
|
|
+ OS_S8:
|
|
|
+ oppostfix:=PF_B;
|
|
|
+ OS_16,
|
|
|
+ OS_S16:
|
|
|
+ oppostfix:=PF_H;
|
|
|
+ OS_32,
|
|
|
+ OS_S32:
|
|
|
+ oppostfix:=PF_None;
|
|
|
+ else
|
|
|
+ InternalError(200308295);
|
|
|
+ end;
|
|
|
+ result:=handle_load_store(list,A_STR,oppostfix,reg,ref);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function tcgarm.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
|
|
|
+ var
|
|
|
+ oppostfix:toppostfix;
|
|
|
+ begin
|
|
|
+ case FromSize of
|
|
|
+ { signed integer registers }
|
|
|
+ OS_8:
|
|
|
+ oppostfix:=PF_B;
|
|
|
+ OS_S8:
|
|
|
+ oppostfix:=PF_SB;
|
|
|
+ OS_16:
|
|
|
+ oppostfix:=PF_H;
|
|
|
+ OS_S16:
|
|
|
+ oppostfix:=PF_SH;
|
|
|
+ OS_32,
|
|
|
+ OS_S32:
|
|
|
+ oppostfix:=PF_None;
|
|
|
+ else
|
|
|
+ InternalError(200308291);
|
|
|
+ end;
|
|
|
+ result:=handle_load_store(list,A_LDR,oppostfix,reg,ref);
|
|
|
+ end;
|
|
|
+
|
|
|
procedure tcgarm.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
|
|
|
var
|
|
|
instr: taicpu;
|
|
@@ -1299,18 +1422,18 @@ unit cgcpu;
|
|
|
end
|
|
|
else
|
|
|
begin
|
|
|
- destreg:=getintregister(list,OS_ADDR);
|
|
|
- a_loadaddr_ref_reg(list,dest,destreg);
|
|
|
- reference_reset_base(dstref,destreg,0);
|
|
|
+ destreg:=getintregister(list,OS_ADDR);
|
|
|
+ a_loadaddr_ref_reg(list,dest,destreg);
|
|
|
+ reference_reset_base(dstref,destreg,0);
|
|
|
|
|
|
- srcreg:=getintregister(list,OS_ADDR);
|
|
|
- a_loadaddr_ref_reg(list,source,srcreg);
|
|
|
- reference_reset_base(srcref,srcreg,0);
|
|
|
+ srcreg:=getintregister(list,OS_ADDR);
|
|
|
+ a_loadaddr_ref_reg(list,source,srcreg);
|
|
|
+ reference_reset_base(srcref,srcreg,0);
|
|
|
|
|
|
- countreg:=getintregister(list,OS_32);
|
|
|
+ countreg:=getintregister(list,OS_32);
|
|
|
|
|
|
// if cs_opt_size in aktoptimizerswitches then
|
|
|
- genloop(len,1);
|
|
|
+ genloop(len,1);
|
|
|
{
|
|
|
else
|
|
|
begin
|
|
@@ -1332,8 +1455,8 @@ unit cgcpu;
|
|
|
list.concat(Taicpu.op_none(A_MOVSB,S_NO));
|
|
|
end;
|
|
|
}
|
|
|
+ end;
|
|
|
end;
|
|
|
- end;
|
|
|
|
|
|
|
|
|
procedure tcgarm.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);
|