|
@@ -50,8 +50,6 @@ type
|
|
|
paraloc: tcgpara); override;
|
|
|
|
|
|
procedure a_call_name(list: taasmoutput; const s: string); override;
|
|
|
- procedure a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean);
|
|
|
-
|
|
|
procedure a_call_reg(list: taasmoutput; reg: tregister); override;
|
|
|
|
|
|
procedure a_op_const_reg(list: taasmoutput; Op: TOpCG; size: TCGSize; a:
|
|
@@ -67,8 +65,11 @@ type
|
|
|
{ move instructions }
|
|
|
procedure a_load_const_reg(list: taasmoutput; size: tcgsize; a: aint; reg:
|
|
|
tregister); override;
|
|
|
+ { stores the contents of register reg to the memory location described by
|
|
|
+ ref }
|
|
|
procedure a_load_reg_ref(list: taasmoutput; fromsize, tosize: tcgsize; reg:
|
|
|
tregister; const ref: treference); override;
|
|
|
+ { loads the memory pointed to by ref into register reg }
|
|
|
procedure a_load_ref_reg(list: taasmoutput; fromsize, tosize: tcgsize; const
|
|
|
Ref: treference; reg: tregister); override;
|
|
|
procedure a_load_reg_reg(list: taasmoutput; fromsize, tosize: tcgsize; reg1,
|
|
@@ -77,6 +78,7 @@ type
|
|
|
{ fpu move instructions }
|
|
|
procedure a_loadfpu_reg_reg(list: taasmoutput; size: tcgsize; reg1, reg2:
|
|
|
tregister); override;
|
|
|
+
|
|
|
procedure a_loadfpu_ref_reg(list: taasmoutput; size: tcgsize; const ref:
|
|
|
treference; reg: tregister); override;
|
|
|
procedure a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg:
|
|
@@ -150,6 +152,8 @@ type
|
|
|
{ returns true if the offset of the given reference can not be represented by a 16 bit
|
|
|
immediate as required by some PowerPC instructions }
|
|
|
function hasLargeOffset(const ref : TReference) : Boolean; inline;
|
|
|
+
|
|
|
+ procedure a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
|
|
|
end;
|
|
|
|
|
|
const
|
|
@@ -258,10 +262,9 @@ begin
|
|
|
else
|
|
|
internalerror(2002072801);
|
|
|
end;
|
|
|
- LOC_VOID:
|
|
|
- begin
|
|
|
- // nothing to do
|
|
|
- end;
|
|
|
+ LOC_VOID:
|
|
|
+ { nothing to do }
|
|
|
+ ;
|
|
|
else
|
|
|
internalerror(2002081103);
|
|
|
end;
|
|
@@ -300,17 +303,17 @@ end;
|
|
|
|
|
|
procedure tcgppc.a_call_name(list: taasmoutput; const s: string);
|
|
|
begin
|
|
|
- a_call_name_direct(list, s, true);
|
|
|
+ a_call_name_direct(list, s, true, true);
|
|
|
end;
|
|
|
|
|
|
-procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean);
|
|
|
+procedure tcgppc.a_call_name_direct(list: taasmoutput; s: string; prependDot : boolean; addNOP : boolean);
|
|
|
begin
|
|
|
- if (prependDot) then begin
|
|
|
- s := '.' + s;
|
|
|
- end;
|
|
|
+ if (prependDot) then
|
|
|
+ s := '.' + s;
|
|
|
list.concat(taicpu.op_sym(A_BL, objectlibrary.newasmsymbol(s, AB_EXTERNAL,
|
|
|
AT_FUNCTION)));
|
|
|
- list.concat(taicpu.op_none(A_NOP));
|
|
|
+ if (addNOP) then
|
|
|
+ list.concat(taicpu.op_none(A_NOP));
|
|
|
{
|
|
|
the compiler does not properly set this flag anymore in pass 1, and
|
|
|
for now we only need it after pass 2 (I hope) (JM)
|
|
@@ -324,35 +327,43 @@ end;
|
|
|
{ calling a procedure by address }
|
|
|
|
|
|
procedure tcgppc.a_call_reg(list: taasmoutput; reg: tregister);
|
|
|
-
|
|
|
var
|
|
|
- tmpreg: tregister;
|
|
|
tmpref: treference;
|
|
|
-
|
|
|
- gotref : treference;
|
|
|
-
|
|
|
begin
|
|
|
- tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
|
|
+ if (not (cs_littlesize in aktglobalswitches)) then begin
|
|
|
+ { load actual function entry (reg contains the reference to the function descriptor)
|
|
|
+ into R0 }
|
|
|
+ reference_reset_base(tmpref, reg, 0);
|
|
|
+ a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_R0);
|
|
|
|
|
|
- reference_reset(tmpref);
|
|
|
- tmpref.offset := 0;
|
|
|
- tmpref.base := reg;
|
|
|
- list.concat(taicpu.op_reg_ref(A_LD, tmpreg, tmpref));
|
|
|
+ { save TOC pointer in stackframe }
|
|
|
+ reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_ELF);
|
|
|
+ a_load_reg_ref(list, OS_ADDR, OS_ADDR, NR_RTOC, tmpref);
|
|
|
|
|
|
-// TODO: GOT change
|
|
|
+ { move actual function pointer to CTR register }
|
|
|
+ list.concat(taicpu.op_reg(A_MTCTR, NR_R0));
|
|
|
|
|
|
-// reference_reset(gotref);
|
|
|
-// tmpref.offset := 40;
|
|
|
-// tmpref.base := rg[R_INTREGISTER].getregister(list, NR_STACK_POINTER_REG);
|
|
|
+ { load new TOC pointer from function descriptor into RTOC register }
|
|
|
+ reference_reset_base(tmpref, reg, tcgsize2size[OS_ADDR]);
|
|
|
+ a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_RTOC);
|
|
|
|
|
|
-// taicpu.op_load_reg_ref(list, OS_INT, OS_INT,
|
|
|
- list.concat(taicpu.op_reg(A_MTCTR, tmpreg));
|
|
|
+ { load new environment pointer from function descriptor into R11 register }
|
|
|
+ reference_reset_base(tmpref, reg, 2*tcgsize2size[OS_ADDR]);
|
|
|
+ a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_R11);
|
|
|
|
|
|
+ { call function }
|
|
|
+ list.concat(taicpu.op_none(A_BCTRL));
|
|
|
+ end else begin
|
|
|
+ { call ptrgl helper routine which expects the pointer to the function descriptor
|
|
|
+ in R11 }
|
|
|
+ a_load_reg_reg(list, OS_ADDR, OS_ADDR, reg, NR_R11);
|
|
|
+ a_call_name_direct(list, 'ptrgl', true, false);
|
|
|
+ end;
|
|
|
+
|
|
|
+ { we need to load the old RTOC from stackframe because we changed it}
|
|
|
+ reference_reset_base(tmpref, NR_STACK_POINTER_REG, LA_RTOC_ELF);
|
|
|
+ a_load_ref_reg(list, OS_ADDR, OS_ADDR, tmpref, NR_RTOC);
|
|
|
|
|
|
- list.concat(taicpu.op_none(A_BCTRL));
|
|
|
- //if target_info.system=system_powerpc_macos then
|
|
|
- // //NOP is not needed here.
|
|
|
- // list.concat(taicpu.op_none(A_NOP));
|
|
|
include(current_procinfo.flags, pi_do_call);
|
|
|
end;
|
|
|
|
|
@@ -389,7 +400,7 @@ procedure tcgppc.a_load_const_reg(list: taasmoutput; size: TCGSize; a: aint;
|
|
|
procedure load32bitconstantR0(list : taasmoutput; size : TCGSize; a : longint;
|
|
|
reg : TRegister);
|
|
|
begin
|
|
|
- // only 16 bit constant? (-2^15 <= a <= +2^15-1)
|
|
|
+ { only 16 bit constant? (-2^15 <= a <= +2^15-1) }
|
|
|
if (a >= low(smallint)) and (a <= high(smallint)) then begin
|
|
|
list.concat(taicpu.op_reg_const(A_LI, reg, smallint(a)));
|
|
|
end else begin
|
|
@@ -474,7 +485,7 @@ procedure tcgppc.a_load_ref_reg(list: taasmoutput; fromsize, tosize: tcgsize;
|
|
|
|
|
|
const
|
|
|
LoadInstr: array[OS_8..OS_S64, boolean, boolean] of TAsmOp =
|
|
|
- { indexed? updating?}
|
|
|
+ { indexed? updating? }
|
|
|
(((A_LBZ, A_LBZU), (A_LBZX, A_LBZUX)),
|
|
|
((A_LHZ, A_LHZU), (A_LHZX, A_LHZUX)),
|
|
|
((A_LWZ, A_LWZU), (A_LWZX, A_LWZUX)),
|
|
@@ -493,26 +504,24 @@ var
|
|
|
ref2: treference;
|
|
|
|
|
|
begin
|
|
|
- { TODO: optimize/take into consideration fromsize/tosize. Will }
|
|
|
- { probably only matter for OS_S8 loads though }
|
|
|
if not (fromsize in [OS_8, OS_S8, OS_16, OS_S16, OS_32, OS_S32, OS_64, OS_S64]) then
|
|
|
internalerror(2002090902);
|
|
|
ref2 := ref;
|
|
|
fixref(list, ref2, tosize);
|
|
|
- { the caller is expected to have adjusted the reference already }
|
|
|
- { in this case }
|
|
|
+ { the caller is expected to have adjusted the reference already
|
|
|
+ in this case }
|
|
|
if (TCGSize2Size[fromsize] >= TCGSize2Size[tosize]) then
|
|
|
fromsize := tosize;
|
|
|
op := loadinstr[fromsize, ref2.index <> NR_NO, false];
|
|
|
- // there is no LWAU instruction, simulate using ADDI and LWA
|
|
|
+ { there is no LWAU instruction, simulate using ADDI and LWA }
|
|
|
if (op = A_LWAU) then begin
|
|
|
list.concat(taicpu.op_reg_reg_const(A_ADDI, reg, reg, ref2.offset));
|
|
|
ref2.offset := 0;
|
|
|
op := A_LWA;
|
|
|
end;
|
|
|
a_load_store(list, op, reg, ref2);
|
|
|
- // sign extend shortint if necessary, since there is no
|
|
|
- // load instruction that does that automatically (JM)
|
|
|
+ { sign extend shortint if necessary, since there is no
|
|
|
+ load instruction that does that automatically (JM) }
|
|
|
if fromsize = OS_S8 then
|
|
|
list.concat(taicpu.op_reg_reg(A_EXTSB, reg, reg));
|
|
|
end;
|
|
@@ -573,8 +582,8 @@ var
|
|
|
ref2: treference;
|
|
|
|
|
|
begin
|
|
|
- { several functions call this procedure with OS_32 or OS_64 }
|
|
|
- { so this makes life easier (FK) }
|
|
|
+ { several functions call this procedure with OS_32 or OS_64
|
|
|
+ so this makes life easier (FK) }
|
|
|
case size of
|
|
|
OS_32, OS_F32:
|
|
|
size := OS_F32;
|
|
@@ -594,7 +603,7 @@ procedure tcgppc.a_loadfpu_reg_ref(list: taasmoutput; size: tcgsize; reg:
|
|
|
|
|
|
const
|
|
|
FpuStoreInstr: array[OS_F32..OS_F64, boolean, boolean] of TAsmOp =
|
|
|
- { indexed? updating?}
|
|
|
+ { indexed? updating? }
|
|
|
(((A_STFS, A_STFSU), (A_STFSX, A_STFSUX)),
|
|
|
((A_STFD, A_STFDU), (A_STFDX, A_STFDUX)));
|
|
|
var
|
|
@@ -635,7 +644,7 @@ var
|
|
|
begin
|
|
|
usereg := false;
|
|
|
if (size in [OS_64, OS_S64]) then begin
|
|
|
- // ts: use register method for 64 bit consts. Sloooooow
|
|
|
+ { ts: use register method for 64 bit consts. Sloooooow }
|
|
|
usereg := true;
|
|
|
end else if (size in [OS_32, OS_S32]) then begin
|
|
|
list.concat(taicpu.op_reg_reg_const(oplo, dst, src, word(a)));
|
|
@@ -652,8 +661,8 @@ begin
|
|
|
end;
|
|
|
ophi := TOpCG2AsmOpConstHi[op];
|
|
|
oplo := TOpCG2AsmOpConstLo[op];
|
|
|
- // peephole optimizations for AND, OR, XOR - can't this be done at
|
|
|
- // some higher level, independent of architecture?
|
|
|
+ { peephole optimizations for AND, OR, XOR - can't this be done at
|
|
|
+ some higher level, independent of architecture? }
|
|
|
if (op in [OP_AND, OP_OR, OP_XOR]) then begin
|
|
|
if (a = 0) then begin
|
|
|
if op = OP_AND then
|
|
@@ -682,8 +691,7 @@ begin
|
|
|
exit;
|
|
|
end;
|
|
|
|
|
|
- { otherwise, the instructions we can generate depend on the }
|
|
|
- { operation }
|
|
|
+ { otherwise, the instructions we can generate depend on the operation }
|
|
|
useReg := false;
|
|
|
case op of
|
|
|
OP_DIV, OP_IDIV:
|
|
@@ -897,8 +905,7 @@ var
|
|
|
bitvalue: boolean;
|
|
|
|
|
|
begin
|
|
|
- { get the bit to extract from the conditional register + its }
|
|
|
- { requested value (0 or 1) }
|
|
|
+ { get the bit to extract from the conditional register + its requested value (0 or 1) }
|
|
|
testbit := ((f.cr - RS_CR0) * 4);
|
|
|
case f.flag of
|
|
|
F_EQ, F_NE:
|
|
@@ -920,8 +927,7 @@ begin
|
|
|
end;
|
|
|
{ load the conditional register in the destination reg }
|
|
|
list.concat(taicpu.op_reg(A_MFCR, reg));
|
|
|
- { we will move the bit that has to be tested to bit 0 by rotating }
|
|
|
- { left }
|
|
|
+ { we will move the bit that has to be tested to bit 0 by rotating left }
|
|
|
testbit := (testbit + 1) and 31;
|
|
|
{ extract bit }
|
|
|
list.concat(taicpu.op_reg_reg_const_const_const(
|
|
@@ -980,13 +986,13 @@ end;
|
|
|
|
|
|
procedure tcgppc.g_proc_entry(list: taasmoutput; localsize: longint;
|
|
|
nostackframe: boolean);
|
|
|
-{ generated the entry code of a procedure/function. Note: localsize is the }
|
|
|
-{ sum of the size necessary for local variables and the maximum possible }
|
|
|
-{ combined size of ALL the parameters of a procedure called by the current }
|
|
|
-{ one. }
|
|
|
-{ This procedure may be called before, as well as after g_return_from_proc }
|
|
|
-{ is called. NOTE registers are not to be allocated through the register }
|
|
|
-{ allocator here, because the register colouring has already occured !! }
|
|
|
+{ generated the entry code of a procedure/function. Note: localsize is the
|
|
|
+ sum of the size necessary for local variables and the maximum possible
|
|
|
+ combined size of ALL the parameters of a procedure called by the current
|
|
|
+ one.
|
|
|
+ This procedure may be called before, as well as after g_return_from_proc
|
|
|
+ is called. NOTE registers are not to be allocated through the register
|
|
|
+ allocator here, because the register colouring has already occured !! }
|
|
|
var
|
|
|
firstregfpu, firstreggpr: TSuperRegister;
|
|
|
href: treference;
|
|
@@ -996,34 +1002,34 @@ var
|
|
|
fprcount, gprcount : aint;
|
|
|
|
|
|
begin
|
|
|
- { CR and LR only have to be saved in case they are modified by the current }
|
|
|
- { procedure, but currently this isn't checked, so save them always }
|
|
|
- { following is the entry code as described in "Altivec Programming }
|
|
|
- { Interface Manual", bar the saving of AltiVec registers }
|
|
|
+ { CR and LR only have to be saved in case they are modified by the current
|
|
|
+ procedure, but currently this isn't checked, so save them always
|
|
|
+ following is the entry code as described in "Altivec Programming
|
|
|
+ Interface Manual", bar the saving of AltiVec registers }
|
|
|
a_reg_alloc(list, NR_STACK_POINTER_REG);
|
|
|
a_reg_alloc(list, NR_R0);
|
|
|
|
|
|
calcFirstUsedFPR(firstregfpu, fprcount);
|
|
|
calcFirstUsedGPR(firstreggpr, gprcount);
|
|
|
|
|
|
- // calculate real stack frame size
|
|
|
+ { calculate real stack frame size }
|
|
|
localsize := tppcprocinfo(current_procinfo).calc_stackframe_size(
|
|
|
gprcount, fprcount);
|
|
|
|
|
|
- // determine whether we need to save the link register
|
|
|
+ { determine whether we need to save the link register }
|
|
|
needslinkreg := ((not (po_assembler in current_procinfo.procdef.procoptions)) and
|
|
|
(pi_do_call in current_procinfo.flags));
|
|
|
|
|
|
- // move link register to r0
|
|
|
+ { move link register to r0 }
|
|
|
if (needslinkreg) then begin
|
|
|
list.concat(taicpu.op_reg(A_MFLR, NR_R0));
|
|
|
end;
|
|
|
- // save old stack frame pointer
|
|
|
+ { save old stack frame pointer }
|
|
|
if (localsize > 0) then begin
|
|
|
a_reg_alloc(list, NR_R12);
|
|
|
list.concat(taicpu.op_reg_reg(A_MR, NR_R12, NR_STACK_POINTER_REG));
|
|
|
end;
|
|
|
- // save registers, FPU first, then GPR
|
|
|
+ { save registers, FPU first, then GPR }
|
|
|
reference_reset_base(href, NR_STACK_POINTER_REG, -8);
|
|
|
if (fprcount > 0) then begin
|
|
|
for regcount := RS_F31 downto firstregfpu do begin
|
|
@@ -1040,15 +1046,15 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
- // VMX registers not supported by FPC atm
|
|
|
+ { VMX registers not supported by FPC atm }
|
|
|
|
|
|
- // we may need to store R0 (=LR) ourselves
|
|
|
+ { we may need to store R0 (=LR) ourselves }
|
|
|
if (needslinkreg) then begin
|
|
|
reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF);
|
|
|
list.concat(taicpu.op_reg_ref(A_STD, NR_R0, href));
|
|
|
end;
|
|
|
|
|
|
- // create stack frame
|
|
|
+ { create stack frame }
|
|
|
if (not nostackframe) and (localsize > 0) then begin
|
|
|
if (localsize <= high(smallint)) then begin
|
|
|
reference_reset_base(href, NR_STACK_POINTER_REG, -localsize);
|
|
@@ -1056,10 +1062,10 @@ begin
|
|
|
end else begin
|
|
|
reference_reset_base(href, NR_NO, -localsize);
|
|
|
|
|
|
- // use R0 for loading the constant (which is definitely > 32k when entering
|
|
|
- // this branch)
|
|
|
- // inlined because it must not use temp registers because register allocations
|
|
|
- // have already been done :(
|
|
|
+ { use R0 for loading the constant (which is definitely > 32k when entering
|
|
|
+ this branch)
|
|
|
+ Inlined at this position because it must not use temp registers because
|
|
|
+ register allocations have already been done :( }
|
|
|
{ Code template:
|
|
|
lis r0,ofs@highest
|
|
|
ori r0,r0,ofs@higher
|
|
@@ -1076,9 +1082,9 @@ begin
|
|
|
list.concat(taicpu.op_reg_reg_reg(A_STDUX, NR_R1, NR_R1, NR_R0));
|
|
|
end;
|
|
|
end;
|
|
|
- // CR register not used by FPC atm
|
|
|
+ { CR register not used by FPC atm }
|
|
|
|
|
|
- // keep R1 allocated???
|
|
|
+ { keep R1 allocated??? }
|
|
|
a_reg_dealloc(list, NR_R0);
|
|
|
end;
|
|
|
|
|
@@ -1097,26 +1103,26 @@ begin
|
|
|
calcFirstUsedFPR(firstregfpu, fprcount);
|
|
|
calcFirstUsedGPR(firstreggpr, gprcount);
|
|
|
|
|
|
- // determine whether we need to restore the link register
|
|
|
+ { determine whether we need to restore the link register }
|
|
|
needslinkreg := ((not (po_assembler in current_procinfo.procdef.procoptions)) and
|
|
|
(pi_do_call in current_procinfo.flags));
|
|
|
- // calculate stack frame
|
|
|
+ { calculate stack frame }
|
|
|
localsize := tppcprocinfo(current_procinfo).calc_stackframe_size(
|
|
|
gprcount, fprcount);
|
|
|
|
|
|
- // CR register not supported
|
|
|
+ { CR register not supported }
|
|
|
|
|
|
- // restore stack pointer
|
|
|
+ { restore stack pointer }
|
|
|
if (not nostackframe) and (localsize > 0) then begin
|
|
|
if (localsize <= high(smallint)) then begin
|
|
|
list.concat(taicpu.op_reg_reg_const(A_ADDI, NR_STACK_POINTER_REG, NR_STACK_POINTER_REG, localsize));
|
|
|
end else begin
|
|
|
reference_reset_base(href, NR_NO, localsize);
|
|
|
|
|
|
- // use R0 for loading the constant (which is definitely > 32k when entering
|
|
|
- // this branch)
|
|
|
- // inlined because it must not use temp registers because register allocations
|
|
|
- // have already been done :(
|
|
|
+ { use R0 for loading the constant (which is definitely > 32k when entering
|
|
|
+ this branch)
|
|
|
+ Inlined because it must not use temp registers because register allocations
|
|
|
+ have already been done :( }
|
|
|
{ Code template:
|
|
|
lis r0,ofs@highest
|
|
|
ori r0,ofs@higher
|
|
@@ -1134,7 +1140,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
- // load registers, FPR first, then GPR
|
|
|
+ { load registers, FPR first, then GPR }
|
|
|
{$note ts:todo change order of loading}
|
|
|
reference_reset_base(href, NR_STACK_POINTER_REG, -tcgsize2size[OS_FLOAT]);
|
|
|
if (fprcount > 0) then begin
|
|
@@ -1152,16 +1158,16 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
- // VMX not supported...
|
|
|
+ { VMX not supported... }
|
|
|
|
|
|
- // restore LR (if needed)
|
|
|
+ { restore LR (if needed) }
|
|
|
if (needslinkreg) then begin
|
|
|
reference_reset_base(href, NR_STACK_POINTER_REG, LA_LR_ELF);
|
|
|
list.concat(taicpu.op_reg_ref(A_LD, NR_R0, href));
|
|
|
list.concat(taicpu.op_reg(A_MTLR, NR_R0));
|
|
|
end;
|
|
|
|
|
|
- // generate return instruction
|
|
|
+ { generate return instruction }
|
|
|
list.concat(taicpu.op_none(A_BLR));
|
|
|
end;
|
|
|
|
|
@@ -1171,7 +1177,7 @@ procedure tcgppc.a_loadaddr_ref_reg(list: taasmoutput; const ref: treference; r:
|
|
|
|
|
|
var
|
|
|
ref2, tmpref: treference;
|
|
|
- // register used to construct address
|
|
|
+ { register used to construct address }
|
|
|
tempreg : TRegister;
|
|
|
|
|
|
begin
|
|
@@ -1185,17 +1191,17 @@ begin
|
|
|
tmpref.offset := ref2.offset;
|
|
|
tmpref.symbol := ref2.symbol;
|
|
|
tmpref.relsymbol := ref2.relsymbol;
|
|
|
- // load 64 bit reference into r. If the reference already has a base register,
|
|
|
- // first load the 64 bit value into a temp register, then add it to the result
|
|
|
- // register rD
|
|
|
+ { load 64 bit reference into r. If the reference already has a base register,
|
|
|
+ first load the 64 bit value into a temp register, then add it to the result
|
|
|
+ register rD }
|
|
|
if (ref2.base <> NR_NO) then begin
|
|
|
- // already have a base register, so allocate a new one
|
|
|
+ { already have a base register, so allocate a new one }
|
|
|
tempreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
|
|
end else begin
|
|
|
tempreg := r;
|
|
|
end;
|
|
|
|
|
|
- // code for loading a reference from a symbol into a register rD.
|
|
|
+ { code for loading a reference from a symbol into a register rD }
|
|
|
(*
|
|
|
lis rX,SYM@highest
|
|
|
ori rX,SYM@higher
|
|
@@ -1213,8 +1219,8 @@ begin
|
|
|
tmpref.refaddr := addr_low;
|
|
|
list.concat(taicpu.op_reg_reg_ref(A_ORI, tempreg, tempreg, tmpref));
|
|
|
|
|
|
- // if there's already a base register, add the temp register contents to
|
|
|
- // the base register
|
|
|
+ { if there's already a base register, add the temp register contents to
|
|
|
+ the base register }
|
|
|
if (ref2.base <> NR_NO) then begin
|
|
|
list.concat(taicpu.op_reg_reg_reg(A_ADD, r, tempreg, ref2.base));
|
|
|
end;
|
|
@@ -1222,8 +1228,8 @@ begin
|
|
|
{ no symbol, but offset <> 0 }
|
|
|
if ref2.base <> NR_NO then begin
|
|
|
a_op_const_reg_reg(list, OP_ADD, OS_64, ref2.offset, ref2.base, r)
|
|
|
- { FixRef makes sure that "(ref.index <> R_NO) and (ref.offset <> 0)" never}
|
|
|
- { occurs, so now only ref.offset has to be loaded }
|
|
|
+ { FixRef makes sure that "(ref.index <> R_NO) and (ref.offset <> 0)" never
|
|
|
+ occurs, so now only ref.offset has to be loaded }
|
|
|
end else begin
|
|
|
a_load_const_reg(list, OS_64, ref2.offset, r)
|
|
|
end;
|
|
@@ -1305,18 +1311,18 @@ begin
|
|
|
|
|
|
{ generate a loop }
|
|
|
if count > 4 then begin
|
|
|
- { the offsets are zero after the a_loadaddress_ref_reg and just }
|
|
|
- { have to be set to 8. I put an Inc there so debugging may be }
|
|
|
- { easier (should offset be different from zero here, it will be }
|
|
|
- { easy to notice in the generated assembler }
|
|
|
+ { the offsets are zero after the a_loadaddress_ref_reg and just
|
|
|
+ have to be set to 8. I put an Inc there so debugging may be
|
|
|
+ easier (should offset be different from zero here, it will be
|
|
|
+ easy to notice in the generated assembler }
|
|
|
inc(dst.offset, 8);
|
|
|
inc(src.offset, 8);
|
|
|
list.concat(taicpu.op_reg_reg_const(A_SUBI, src.base, src.base, 8));
|
|
|
list.concat(taicpu.op_reg_reg_const(A_SUBI, dst.base, dst.base, 8));
|
|
|
countreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
|
|
a_load_const_reg(list, OS_32, count, countreg);
|
|
|
- { explicitely allocate R_0 since it can be used safely here }
|
|
|
- { (for holding date that's being copied) }
|
|
|
+ { explicitely allocate R_0 since it can be used safely here
|
|
|
+ (for holding date that's being copied) }
|
|
|
a_reg_alloc(list, NR_F0);
|
|
|
objectlibrary.getjumplabel(lab);
|
|
|
a_label(list, lab);
|
|
@@ -1382,10 +1388,10 @@ begin
|
|
|
(torddef(def).typ in [u64bit, u16bit, u32bit, u8bit, uchar,
|
|
|
bool8bit, bool16bit, bool32bit]))) then
|
|
|
begin
|
|
|
- // ... instruction setting overflow flag ...
|
|
|
- // mfxerf R0
|
|
|
- // mtcrf 128, R0
|
|
|
- // ble cr0, label
|
|
|
+ { ... instructions setting overflow flag ...
|
|
|
+ mfxerf R0
|
|
|
+ mtcrf 128, R0
|
|
|
+ ble cr0, label }
|
|
|
list.concat(taicpu.op_reg(A_MFXER, NR_R0));
|
|
|
list.concat(taicpu.op_const_reg(A_MTCRF, 128, NR_R0));
|
|
|
flags.cr := RS_CR0;
|
|
@@ -1426,15 +1432,15 @@ procedure tcgppc.g_intf_wrapper(list: TAAsmoutput; procdef: tprocdef; const
|
|
|
{ add support for offsets > 16 bit }
|
|
|
internalerror(200510201);
|
|
|
list.concat(taicpu.op_reg_ref(A_LD, NR_R11, href));
|
|
|
- // the loaded reference is a function descriptor reference, so deref again
|
|
|
- // (at ofs 0 there's the real pointer)
|
|
|
+ { the loaded reference is a function descriptor reference, so deref again
|
|
|
+ (at ofs 0 there's the real pointer) }
|
|
|
{$warning ts:TODO: update GOT reference}
|
|
|
reference_reset_base(href, NR_R11, 0);
|
|
|
list.concat(taicpu.op_reg_ref(A_LD, NR_R11, href));
|
|
|
|
|
|
list.concat(taicpu.op_reg(A_MTCTR, NR_R11));
|
|
|
list.concat(taicpu.op_none(A_BCTR));
|
|
|
- // NOP needed for the linker...?
|
|
|
+ { NOP needed for the linker...? }
|
|
|
list.concat(taicpu.op_none(A_NOP));
|
|
|
end;
|
|
|
|
|
@@ -1464,11 +1470,10 @@ begin
|
|
|
{ set param1 interface to self }
|
|
|
g_adjust_self_value(list, procdef, ioffset);
|
|
|
|
|
|
- { case 4 }
|
|
|
if po_virtualmethod in procdef.procoptions then begin
|
|
|
loadvmttor11;
|
|
|
op_onr11methodaddr;
|
|
|
- end { case 0 } else
|
|
|
+ end else
|
|
|
{$note ts:todo add GOT change?? - think not needed :) }
|
|
|
list.concat(taicpu.op_sym(A_B,
|
|
|
objectlibrary.newasmsymbol('.' + procdef.mangledname, AB_EXTERNAL,
|