|
@@ -37,8 +37,6 @@ unit ncpuset;
|
|
|
procedure optimizevalues(var max_linear_list:aint;var max_dist:aword);override;
|
|
|
function has_jumptable : boolean;override;
|
|
|
procedure genjumptable(hp : pcaselabel;min_,max_ : aint);override;
|
|
|
- public
|
|
|
- function pass_1:tnode;override;
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -65,18 +63,9 @@ unit ncpuset;
|
|
|
end;
|
|
|
|
|
|
|
|
|
- function tcpucasenode.pass_1:tnode;
|
|
|
- begin
|
|
|
- result:=inherited pass_1;
|
|
|
- { TODO: ABI-compliant position-independent case code does not involve GOT }
|
|
|
- if (cs_create_pic in current_settings.moduleswitches) and
|
|
|
- (tf_pic_uses_got in target_info.flags) then
|
|
|
- include(current_procinfo.flags,pi_needs_got);
|
|
|
- end;
|
|
|
-
|
|
|
-
|
|
|
procedure tcpucasenode.genjumptable(hp : pcaselabel;min_,max_ : aint);
|
|
|
var
|
|
|
+ base,
|
|
|
table : tasmlabel;
|
|
|
last : TConstExprInt;
|
|
|
indexreg,jmpreg,basereg : tregister;
|
|
@@ -91,9 +80,9 @@ unit ncpuset;
|
|
|
genitem(list,t^.less);
|
|
|
{ fill possible hole }
|
|
|
for i:=last.svalue+1 to t^._low.svalue-1 do
|
|
|
- list.concat(Tai_const.Create_sym(elselabel));
|
|
|
+ list.concat(Tai_const.Create_rel_sym(aitconst_ptr,base,elselabel));
|
|
|
for i:=t^._low.svalue to t^._high.svalue do
|
|
|
- list.concat(Tai_const.Create_sym(blocklabel(t^.blockid)));
|
|
|
+ list.concat(Tai_const.Create_rel_sym(aitconst_ptr,base,blocklabel(t^.blockid)));
|
|
|
last:=t^._high;
|
|
|
if assigned(t^.greater) then
|
|
|
genitem(list,t^.greater);
|
|
@@ -112,26 +101,45 @@ unit ncpuset;
|
|
|
indexreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
|
|
cg.a_op_const_reg_reg(current_asmdata.CurrAsmList,OP_SHL,OS_ADDR,2,hregister,indexreg);
|
|
|
{ create reference }
|
|
|
- reference_reset_symbol(href,table,0,sizeof(pint));
|
|
|
- href.offset:=(-aint(min_))*4;
|
|
|
+ current_asmdata.getjumplabel(base);
|
|
|
+ cg.a_label(current_asmdata.CurrAsmList,base);
|
|
|
+ reference_reset_symbol(href,table,(-aint(min_))*4,sizeof(pint));
|
|
|
+ href.relsymbol:=base;
|
|
|
+ { Generate the following code:
|
|
|
+ .Lbase:
|
|
|
+ call .+8 # mov %pc,%o7
|
|
|
+ sethi %hi(.LTable-.Lbase),%basereg
|
|
|
+ or %basereg,%lo(.LTable-.Lbase),%basereg
|
|
|
+ add %indexreg,%basereg%,%basereg
|
|
|
+ ld [%o7+%basereg],%jmpreg
|
|
|
+ jmp %o7+%jmpreg }
|
|
|
+ { CALL overwrites %o7, tell reg.allocator about that }
|
|
|
+ cg.getcpuregister(current_asmdata.CurrAsmList,NR_O7);
|
|
|
+ current_asmdata.CurrAsmList.concat(taicpu.op_sym_ofs(A_CALL,base,8));
|
|
|
+
|
|
|
basereg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
|
|
- cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,basereg);
|
|
|
+ { TODO: incorporate handling such references into cg.a_loadaddr_ref_reg? }
|
|
|
+ href.refaddr:=addr_high;
|
|
|
+ current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_SETHI,href,basereg));
|
|
|
+ href.refaddr:=addr_low;
|
|
|
+ current_asmdata.CurrAsmList.concat(taicpu.op_reg_ref_reg(A_OR,basereg,href,basereg));
|
|
|
+ { add index }
|
|
|
+ cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,basereg,indexreg,basereg);
|
|
|
|
|
|
jmpreg:=cg.getaddressregister(current_asmdata.CurrAsmList);
|
|
|
-
|
|
|
- reference_reset(href,sizeof(pint));
|
|
|
- href.index:=indexreg;
|
|
|
- href.base:=basereg;
|
|
|
+ reference_reset_base(href,NR_O7,0,sizeof(pint));
|
|
|
+ href.index:=basereg;
|
|
|
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,jmpreg);
|
|
|
-
|
|
|
- current_asmdata.CurrAsmList.concat(taicpu.op_reg(A_JMP,jmpreg));
|
|
|
+ href.index:=jmpreg;
|
|
|
+ href.refaddr:=addr_full;
|
|
|
+ current_asmdata.CurrAsmList.concat(taicpu.op_ref(A_JMP,href));
|
|
|
{ Delay slot }
|
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(A_NOP));
|
|
|
+ cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_O7);
|
|
|
{ generate jump table }
|
|
|
- new_section(current_procinfo.aktlocaldata,sec_data,current_procinfo.procdef.mangledname,sizeof(pint));
|
|
|
- current_procinfo.aktlocaldata.concat(Tai_label.Create(table));
|
|
|
last:=min_;
|
|
|
- genitem(current_procinfo.aktlocaldata,hp);
|
|
|
+ cg.a_label(current_asmdata.CurrAsmList,table);
|
|
|
+ genitem(current_asmdata.CurrAsmList,hp);
|
|
|
end;
|
|
|
|
|
|
|