|
@@ -469,11 +469,12 @@ procedure fixup_jmps(list: TAsmList);
|
|
|
var
|
|
|
p,pdelayslot: tai;
|
|
|
newcomment: tai_comment;
|
|
|
- newjmp,newnoop: taicpu;
|
|
|
+ newins,newjmp,newnoop: taicpu;
|
|
|
labelpositions: TFPList;
|
|
|
instrpos: ptrint;
|
|
|
l: tasmlabel;
|
|
|
inserted_something: boolean;
|
|
|
+ href: treference;
|
|
|
begin
|
|
|
// if certainly not enough instructions to cause an overflow, dont bother
|
|
|
if (list.count <= (high(smallint) div 4)) then
|
|
@@ -541,11 +542,36 @@ procedure fixup_jmps(list: TAsmList);
|
|
|
(ptruint(abs(ptrint(labelpositions[tasmlabel(taicpu(p).oper[0]^.ref^.symbol).labelnr]-instrpos)) - (low(smallint) div 4)) > ptruint((high(smallint) - low(smallint)) div 4)) then
|
|
|
{$pop}
|
|
|
begin
|
|
|
- { This is not PIC safe }
|
|
|
- taicpu(p).opcode:=A_J;
|
|
|
- newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into A_J'));
|
|
|
- list.insertbefore(newcomment,p);
|
|
|
- end;
|
|
|
+ if (cs_create_pic in current_settings.moduleswitches) then
|
|
|
+ begin
|
|
|
+ newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into PIC sequence'));
|
|
|
+ list.insertbefore(newcomment,p);
|
|
|
+ href:=taicpu(p).oper[0]^.ref^;
|
|
|
+ href.refaddr:=addr_pic;
|
|
|
+ href.base:=NR_GP;
|
|
|
+ newins:=taicpu.op_reg_ref(A_LW,NR_PIC_FUNC,href);
|
|
|
+ newins.fileinfo:=taicpu(p).fileinfo;
|
|
|
+ list.insertbefore(newins,p);
|
|
|
+ inc(instrpos,2);
|
|
|
+ if (href.symbol.bind=AB_LOCAL) then
|
|
|
+ begin
|
|
|
+ href.refaddr:=addr_low;
|
|
|
+ href.base:=NR_NO;
|
|
|
+ newins:=taicpu.op_reg_reg_ref(A_ADDIU,NR_PIC_FUNC,NR_PIC_FUNC,href);
|
|
|
+ newins.fileinfo:=taicpu(p).fileinfo;
|
|
|
+ list.insertbefore(newins,p);
|
|
|
+ inc(instrpos,2);
|
|
|
+ end;
|
|
|
+ taicpu(p).opcode:=A_JR;
|
|
|
+ taicpu(p).loadreg(0,NR_PIC_FUNC);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ taicpu(p).opcode:=A_J;
|
|
|
+ newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BA changed into A_J'));
|
|
|
+ list.insertbefore(newcomment,p);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
A_BC:
|
|
|
if (taicpu(p).ops=3) and (taicpu(p).oper[2]^.typ = top_ref) and
|
|
|
assigned(taicpu(p).oper[2]^.ref^.symbol) and
|
|
@@ -574,11 +600,39 @@ procedure fixup_jmps(list: TAsmList);
|
|
|
// add a new unconditional jump between this jump and the label
|
|
|
newcomment:=tai_comment.create(strpnew('fixup_jmps, A_BXX changed into A_BNOTXX label;A_J;label:'));
|
|
|
list.insertbefore(newcomment,p);
|
|
|
- newjmp := taicpu.op_sym(A_J,taicpu(p).oper[2]^.ref^.symbol);
|
|
|
- newjmp.is_jmp := true;
|
|
|
- newjmp.fileinfo := taicpu(p).fileinfo;
|
|
|
- list.insertafter(newjmp,pdelayslot);
|
|
|
- inc(instrpos,2);
|
|
|
+ if (cs_create_pic in current_settings.moduleswitches) then
|
|
|
+ begin
|
|
|
+ reference_reset_symbol(href,taicpu(p).oper[2]^.ref^.symbol,0,sizeof(pint));
|
|
|
+ href.refaddr:=addr_pic;
|
|
|
+ href.base:=NR_GP;
|
|
|
+ newins:=taicpu.op_reg_ref(A_LW,NR_PIC_FUNC,href);
|
|
|
+ newins.fileinfo:=taicpu(p).fileinfo;
|
|
|
+ list.insertafter(newins,pdelayslot);
|
|
|
+ pdelayslot:=newins;
|
|
|
+ inc(instrpos,2);
|
|
|
+ if (href.symbol.bind=AB_LOCAL) then
|
|
|
+ begin
|
|
|
+ href.base:=NR_NO;
|
|
|
+ href.refaddr:=addr_low;
|
|
|
+ newins:=taicpu.op_reg_reg_ref(A_ADDIU,NR_PIC_FUNC,NR_PIC_FUNC,href);
|
|
|
+ newins.fileinfo:=taicpu(p).fileinfo;
|
|
|
+ list.insertafter(newins,pdelayslot);
|
|
|
+ pdelayslot:=newins;
|
|
|
+ inc(instrpos,2);
|
|
|
+ end;
|
|
|
+ newjmp:=taicpu.op_reg(A_JR,NR_PIC_FUNC);
|
|
|
+ newjmp.fileinfo:=taicpu(p).fileinfo;
|
|
|
+ list.insertafter(newjmp,pdelayslot);
|
|
|
+ inc(instrpos,2);
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ newjmp := taicpu.op_sym(A_J,taicpu(p).oper[2]^.ref^.symbol);
|
|
|
+ newjmp.is_jmp := true;
|
|
|
+ newjmp.fileinfo := taicpu(p).fileinfo;
|
|
|
+ list.insertafter(newjmp,pdelayslot);
|
|
|
+ inc(instrpos,2);
|
|
|
+ end;
|
|
|
{ Add a delay slot for new A_J instruction }
|
|
|
newnoop:=taicpu.op_none(A_NOP);
|
|
|
newnoop.fileinfo := taicpu(p).fileinfo;
|