|
@@ -36,41 +36,44 @@ unit cgcpu;
|
|
|
{ left to right), this allows to move the parameter to }
|
|
|
{ register, if the cpu supports register calling }
|
|
|
{ conventions }
|
|
|
- procedure a_param_reg(list : paasmoutput;size : tcgsize;r : tregister;nr : longint);virtual;
|
|
|
- procedure a_param_const(list : paasmoutput;size : tcgsize;a : aword;nr : longint);virtual;
|
|
|
- procedure a_param_ref(list : paasmoutput;size : tcgsize;const r : treference;nr : longint);virtual;
|
|
|
- procedure a_paramaddr_ref(list : paasmoutput;const r : treference;nr : longint);virtual;
|
|
|
+ procedure a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;nr : longint);virtual;
|
|
|
+ procedure a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);virtual;
|
|
|
+ procedure a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);virtual;
|
|
|
+ procedure a_paramaddr_ref(list : taasmoutput;const r : treference;nr : longint);virtual;
|
|
|
|
|
|
|
|
|
- procedure a_call_name(list : paasmoutput;const s : string;
|
|
|
+ procedure a_call_name(list : taasmoutput;const s : string;
|
|
|
offset : longint);virtual;
|
|
|
|
|
|
- procedure a_op_reg_const(list : paasmoutput; Op: TOpCG; size: TCGSize; reg: TRegister; a: AWord); virtual;
|
|
|
+ procedure a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; reg: TRegister); virtual;
|
|
|
+ procedure a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister); virtual;
|
|
|
|
|
|
{ move instructions }
|
|
|
- procedure a_load_const_reg(list : paasmoutput; size: tcgsize; a : aword;reg : tregister);virtual;
|
|
|
- procedure a_load_reg_ref(list : paasmoutput; size: tcgsize; reg : tregister;const ref2 : treference);virtual;
|
|
|
- procedure a_load_ref_reg(list : paasmoutput;size : tcgsize;const Ref2 : treference;reg : tregister);virtual;
|
|
|
- procedure a_load_reg_reg(list : paasmoutput;size : tcgsize;reg1,reg2 : tregister);virtual;
|
|
|
+ procedure a_load_const_reg(list : taasmoutput; size: tcgsize; a : aword;reg : tregister);virtual;
|
|
|
+ procedure a_load_reg_ref(list : taasmoutput; size: tcgsize; reg : tregister;const ref2 : treference);virtual;
|
|
|
+ procedure a_load_ref_reg(list : taasmoutput;size : tcgsize;const Ref2 : treference;reg : tregister);virtual;
|
|
|
+ procedure a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);virtual;
|
|
|
|
|
|
{ comparison operations }
|
|
|
- procedure a_cmp_const_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
|
|
+ procedure a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
|
|
l : pasmlabel);virtual;
|
|
|
- procedure a_cmp_reg_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : pasmlabel);
|
|
|
- procedure a_jmp_cond(list : paasmoutput;cond : TOpCmp;l: pasmlabel);
|
|
|
+ procedure a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : pasmlabel);
|
|
|
|
|
|
+ procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: pasmlabel);
|
|
|
+ procedure g_flags2reg(const f: TAsmCond; reg: TRegister); abstract;
|
|
|
|
|
|
- procedure g_stackframe_entry_sysv(list : paasmoutput;localsize : longint);
|
|
|
- procedure g_stackframe_entry_mac(list : paasmoutput;localsize : longint);
|
|
|
- procedure g_stackframe_entry(list : paasmoutput;localsize : longint);virtual;
|
|
|
- procedure g_restore_frame_pointer(list : paasmoutput);virtual;
|
|
|
- procedure g_return_from_proc(list : paasmoutput;parasize : aword); virtual;
|
|
|
- procedure g_return_from_proc_sysv(list : paasmoutput;parasize : aword);
|
|
|
- procedure g_return_from_proc_mac(list : paasmoutput;parasize : aword);
|
|
|
|
|
|
- procedure a_loadaddress_ref_reg(list : paasmoutput;const ref2 : treference;r : tregister);virtual;
|
|
|
+ procedure g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
|
|
|
+ procedure g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
|
|
|
+ procedure g_stackframe_entry(list : taasmoutput;localsize : longint);virtual;
|
|
|
+ procedure g_restore_frame_pointer(list : taasmoutput);virtual;
|
|
|
+ procedure g_return_from_proc(list : taasmoutput;parasize : aword); virtual;
|
|
|
+ procedure g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
|
|
|
+ procedure g_return_from_proc_mac(list : taasmoutput;parasize : aword);
|
|
|
|
|
|
- procedure g_concatcopy(list : paasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);virtual;
|
|
|
+ procedure a_loadaddress_ref_reg(list : taasmoutput;const ref2 : treference;r : tregister);virtual;
|
|
|
+
|
|
|
+ procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);virtual;
|
|
|
|
|
|
|
|
|
private
|
|
@@ -79,19 +82,19 @@ unit cgcpu;
|
|
|
{ OpLo reg1, reg2, (a and $ffff) and/or }
|
|
|
{ OpHi reg1, reg2, (a shr 16) }
|
|
|
{ depending on the value of a }
|
|
|
- procedure a_op_reg_reg_const32(list: paasmOutPut; oplo, ophi: tasmop;
|
|
|
+ procedure a_op_reg_reg_const32(list: taasmoutput; oplo, ophi: tasmop;
|
|
|
reg1, reg2: tregister; a: aword);
|
|
|
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
|
|
{ base to the value of the index if (base = R_NO). }
|
|
|
procedure fixref(var ref: treference);
|
|
|
|
|
|
{ contains the common code of a_load_reg_ref and a_load_ref_reg }
|
|
|
- procedure a_load_store(list:paasmoutput;op: tasmop;reg:tregister;
|
|
|
+ procedure a_load_store(list:taasmoutput;op: tasmop;reg:tregister;
|
|
|
var ref: treference);
|
|
|
|
|
|
{ creates the correct branch instruction for a given combination }
|
|
|
{ of asmcondflags and destination addressing mode }
|
|
|
- procedure a_jmp(list: paasmoutput; op: tasmop;
|
|
|
+ procedure a_jmp(list: taasmoutput; op: tasmop;
|
|
|
c: tasmcondflags; l: pasmlabel);
|
|
|
|
|
|
end;
|
|
@@ -128,7 +131,7 @@ const
|
|
|
{ parameter passing... Still needs extra support from the processor }
|
|
|
{ independent code generator }
|
|
|
|
|
|
- procedure tcgppc.a_param_reg(list : paasmoutput;size : tcgsize;r : tregister;nr : longint);
|
|
|
+ procedure tcgppc.a_param_reg(list : taasmoutput;size : tcgsize;r : tregister;nr : longint);
|
|
|
|
|
|
var ref: treference;
|
|
|
|
|
@@ -147,7 +150,7 @@ const
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.a_param_const(list : paasmoutput;size : tcgsize;a : aword;nr : longint);
|
|
|
+ procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aword;nr : longint);
|
|
|
|
|
|
var ref: treference;
|
|
|
|
|
@@ -166,7 +169,7 @@ const
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.a_param_ref(list : paasmoutput;size : tcgsize;const r : treference;nr : longint);
|
|
|
+ procedure tcgppc.a_param_ref(list : taasmoutput;size : tcgsize;const r : treference;nr : longint);
|
|
|
|
|
|
var ref: treference;
|
|
|
tmpreg: tregister;
|
|
@@ -189,7 +192,7 @@ const
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.a_paramaddr_ref(list : paasmoutput;const r : treference;nr : longint);
|
|
|
+ procedure tcgppc.a_paramaddr_ref(list : taasmoutput;const r : treference;nr : longint);
|
|
|
|
|
|
var ref: treference;
|
|
|
tmpreg: tregister;
|
|
@@ -213,36 +216,36 @@ const
|
|
|
|
|
|
{ calling a code fragment by name }
|
|
|
|
|
|
- procedure tcgppc.a_call_name(list : paasmoutput;const s : string;
|
|
|
+ procedure tcgppc.a_call_name(list : taasmoutput;const s : string;
|
|
|
offset : longint);
|
|
|
|
|
|
begin
|
|
|
{ save our RTOC register value. Only necessary when doing pointer based }
|
|
|
{ calls or cross TOC calls, but currently done always }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STW,R_RTOC,
|
|
|
- new_reference(stack_pointer,LA_RTOC))));
|
|
|
- list^.concat(new(paicpu,op_sym(A_BL,newasmsymbol(s))));
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LWZ,R_RTOC,
|
|
|
- new_reference(stack_pointer,LA_RTOC))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STW,R_RTOC,
|
|
|
+ new_reference(stack_pointer,LA_RTOC)));
|
|
|
+ list.concat(taicpu.op_sym(A_BL,newasmsymbol(s)));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LWZ,R_RTOC,
|
|
|
+ new_reference(stack_pointer,LA_RTOC)));
|
|
|
end;
|
|
|
|
|
|
{********************** load instructions ********************}
|
|
|
|
|
|
- procedure tcgppc.a_load_const_reg(list : paasmoutput; size: TCGSize; a : aword; reg : TRegister);
|
|
|
+ procedure tcgppc.a_load_const_reg(list : taasmoutput; size: TCGSize; a : aword; reg : TRegister);
|
|
|
|
|
|
begin
|
|
|
If (a and $ffff) <> 0 Then
|
|
|
Begin
|
|
|
- list^.concat(new(paicpu,op_reg_const(A_LI,reg,a and $ffff)));
|
|
|
+ list.concat(taicpu.op_reg_const(A_LI,reg,a and $ffff));
|
|
|
If (a shr 16) <> 0 Then
|
|
|
- list^.concat(new(paicpu,op_reg_const(A_ADDIS,reg,
|
|
|
- (a shr 16)+ord(smallint(a and $ffff) < 0))))
|
|
|
+ list.concat(taicpu.op_reg_const(A_ADDIS,reg,
|
|
|
+ (a shr 16)+ord(smallint(a and $ffff) < 0)))
|
|
|
End
|
|
|
Else
|
|
|
- list^.concat(new(paicpu,op_reg_const(A_LIS,reg,a shr 16)));
|
|
|
+ list.concat(taicpu.op_reg_const(A_LIS,reg,a shr 16));
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_load_reg_ref(list : paasmoutput; size: TCGSize; reg : tregister;const ref2 : treference);
|
|
|
+ procedure tcgppc.a_load_reg_ref(list : taasmoutput; size: TCGSize; reg : tregister;const ref2 : treference);
|
|
|
|
|
|
Var
|
|
|
op: TAsmOp;
|
|
@@ -255,7 +258,7 @@ const
|
|
|
a_load_store(list,op,reg,ref);
|
|
|
End;
|
|
|
|
|
|
- procedure tcgppc.a_load_ref_reg(list : paasmoutput;size : tcgsize;const ref2: treference;reg : tregister);
|
|
|
+ procedure tcgppc.a_load_ref_reg(list : taasmoutput;size : tcgsize;const ref2: treference;reg : tregister);
|
|
|
|
|
|
Var
|
|
|
op: TAsmOp;
|
|
@@ -269,13 +272,13 @@ const
|
|
|
a_load_store(list,op,reg,ref);
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_load_reg_reg(list : paasmoutput;size : tcgsize;reg1,reg2 : tregister);
|
|
|
+ procedure tcgppc.a_load_reg_reg(list : taasmoutput;size : tcgsize;reg1,reg2 : tregister);
|
|
|
|
|
|
begin
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MR,reg2,reg1)));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MR,reg2,reg1));
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_op_reg_const(list : paasmoutput; Op: TOpCG; size: TCGSize; reg: TRegister; a: AWord);
|
|
|
+ procedure tcgppc.a_op_const_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; a: AWord; reg: TRegister);
|
|
|
|
|
|
var scratch_register: TRegister;
|
|
|
|
|
@@ -284,13 +287,13 @@ const
|
|
|
OP_DIV, OP_IDIV, OP_IMUL, OP_MUL:
|
|
|
If (Op = OP_IMUL) And (longint(a) >= -32768) And
|
|
|
(longint(a) <= 32767) Then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_MULLI,reg,reg,a)))
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_MULLI,reg,reg,a))
|
|
|
Else
|
|
|
Begin
|
|
|
scratch_register := get_scratch_reg(list);
|
|
|
a_load_const_reg(list, OS_32, a, scratch_register);
|
|
|
- list^.concat(new(paicpu,op_reg_reg_reg(TOpCG2AsmOpLo[Op],
|
|
|
- reg,reg,scratch_register)));
|
|
|
+ list.concat(taicpu.op_reg_reg_reg(TOpCG2AsmOpLo[Op],
|
|
|
+ reg,reg,scratch_register));
|
|
|
free_scratch_reg(list,scratch_register);
|
|
|
End;
|
|
|
OP_ADD, OP_AND, OP_OR, OP_SUB,OP_XOR:
|
|
@@ -299,8 +302,8 @@ const
|
|
|
OP_SHL,OP_SHR,OP_SAR:
|
|
|
Begin
|
|
|
if (a and 31) <> 0 Then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(
|
|
|
- TOpCG2AsmOpLo[Op],reg,reg,a and 31)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(
|
|
|
+ TOpCG2AsmOpLo[Op],reg,reg,a and 31));
|
|
|
If (a shr 5) <> 0 Then
|
|
|
InternalError(68991);
|
|
|
End
|
|
@@ -308,10 +311,24 @@ const
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+ procedure tcgppc.a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; reg1, reg2: TRegister);
|
|
|
+
|
|
|
+ const
|
|
|
+ op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
|
|
|
+ (A_ADD,A_AND,A_DIVWU,A_DIVW,A_MULLW,A_MULLW,A_NEG,A_NOT,A_OR,
|
|
|
+ A_SRAW,A_SLW,A_SRW,A_SUB,A_XOR)
|
|
|
+
|
|
|
+ begin
|
|
|
+ Case Op of
|
|
|
+ OP_NEG,OP_NOT:
|
|
|
+ list.concat(taicpu.op_reg_reg(op_reg_reg_opcg2asmop[op],size,reg2,reg2));
|
|
|
+ else
|
|
|
+ list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],size,reg2,reg1,reg2));
|
|
|
+ end;
|
|
|
|
|
|
{*************** compare instructructions ****************}
|
|
|
|
|
|
- procedure tcgppc.a_cmp_const_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
|
|
+ procedure tcgppc.a_cmp_const_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
|
|
|
l : pasmlabel);
|
|
|
|
|
|
var p: paicpu;
|
|
@@ -322,29 +339,29 @@ const
|
|
|
signed := cmp_op in [OC_GT,OC_LT,OC_GTE,OC_LTE];
|
|
|
If signed Then
|
|
|
If (longint(a) >= -32768) and (longint(a) <= 32767) Then
|
|
|
- list^.concat(new(paicpu,op_const_reg_const(A_CMPI,0,reg,a)))
|
|
|
+ list.concat(taicpu.op_const_reg_const(A_CMPI,0,reg,a))
|
|
|
else
|
|
|
begin
|
|
|
scratch_register := get_scratch_reg(list);
|
|
|
a_load_const_reg(list,OS_32,a,scratch_register);
|
|
|
- list^.concat(new(paicpu,op_const_reg_reg(A_CMP,0,reg,scratch_register)));
|
|
|
+ list.concat(taicpu.op_const_reg_reg(A_CMP,0,reg,scratch_register));
|
|
|
free_scratch_reg(list,scratch_register);
|
|
|
end
|
|
|
else
|
|
|
if (a <= $ffff) then
|
|
|
- list^.concat(new(paicpu,op_const_reg_const(A_CMPLI,0,reg,a)))
|
|
|
+ list.concat(taicpu.op_const_reg_const(A_CMPLI,0,reg,a))
|
|
|
else
|
|
|
begin
|
|
|
scratch_register := get_scratch_reg(list);
|
|
|
a_load_const_reg(list,OS_32,a,scratch_register);
|
|
|
- list^.concat(new(paicpu,op_const_reg_reg(A_CMPL,0,reg,scratch_register)));
|
|
|
+ list.concat(taicpu.op_const_reg_reg(A_CMPL,0,reg,scratch_register));
|
|
|
free_scratch_reg(list,scratch_register);
|
|
|
end;
|
|
|
a_jmp(list,A_BC,TOpCmp2AsmCond[cmp_op],l);
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.a_cmp_reg_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;
|
|
|
+ procedure tcgppc.a_cmp_reg_reg_label(list : taasmoutput;size : tcgsize;cmp_op : topcmp;
|
|
|
reg1,reg2 : tregister;l : pasmlabel);
|
|
|
|
|
|
var p: paicpu;
|
|
@@ -354,19 +371,70 @@ const
|
|
|
if cmp_op in [OC_GT,OC_LT,OC_GTE,OC_LTE] then
|
|
|
op := A_CMP
|
|
|
else op := A_CMPL;
|
|
|
- list^.concat(new(paicpu,op_const_reg_reg(op,0,reg1,reg2)));
|
|
|
+ list.concat(taicpu.op_const_reg_reg(op,0,reg1,reg2));
|
|
|
a_jmp(list,A_BC,TOpCmp2AsmCond[cmp_op],l);
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_jmp_cond(list : paasmoutput;cond : TOpCmp;l: pasmlabel);
|
|
|
+ procedure tcgppc.a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: pasmlabel);
|
|
|
|
|
|
- begin
|
|
|
- a_jmp(list,A_BC,TOpCmp2AsmCond[cond],l);
|
|
|
- end;
|
|
|
+ begin
|
|
|
+ a_jmp(list,A_BC,TOpCmp2AsmCond[cond],l);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ procedure tcgppc.g_flags2reg(list: taasmoutput; const f: TAsmCond; reg: TRegister);
|
|
|
+
|
|
|
+ var
|
|
|
+ testbit: byte;
|
|
|
+ bitvalue: boolean;
|
|
|
+ begin
|
|
|
+ { get the bit to extract from the conditional register + its }
|
|
|
+ { requested value (0 or 1) }
|
|
|
+ case simple of
|
|
|
+ false:
|
|
|
+ begin
|
|
|
+ { we don't generate this in the compiler }
|
|
|
+ internalerror(200109062);
|
|
|
+ end;
|
|
|
+ true:
|
|
|
+ case f.cond of
|
|
|
+ C_None:
|
|
|
+ internalerror(200109063);
|
|
|
+ C_LT..C_NU:
|
|
|
+ begin
|
|
|
+ testbit := (ord(f.cr) - ord(R_CR0))*4;
|
|
|
+ inc(testbit,AsmCondFlag2BI[f.cond]);
|
|
|
+ bitvalue := AsmCondFlagTF[f.cond];
|
|
|
+ end;
|
|
|
+ C_T,C_F,C_DNZT,C_DNZF,C_DZT,C_DZF:
|
|
|
+ begin
|
|
|
+ testbit := f.crbit
|
|
|
+ bitvalue := AsmCondFlagTF[f.cond];
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ internalerror(200109064);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ { load thge conditional register in the destination reg }
|
|
|
+ list.concat(taicpu.create(op_reg_reg(A_MFCR,reg)));
|
|
|
+ { we will move the bit that has to be tested to bit 0 -> rotate }
|
|
|
+ { left by bitpos+1 (remember, this is big-endian!) }
|
|
|
+ if bitpos <> 31 then
|
|
|
+ inc(bitpos)
|
|
|
+ else
|
|
|
+ bitpos := 0;
|
|
|
+ { extract bit }
|
|
|
+ list.concat(taicpu.create(op_reg_reg_const_const_const(
|
|
|
+ A_RLWINM,reg,reg,bitpos,31,31)));
|
|
|
+ { if we need the inverse, xor with 1 }
|
|
|
+ if not bitvalue then
|
|
|
+ list.concat(taicpu.create(op_reg_reg_const(A_XORI,reg,reg,1)));
|
|
|
+ end;
|
|
|
+
|
|
|
|
|
|
{ *********** entry/exit code and address loading ************ }
|
|
|
|
|
|
- procedure tcgppc.g_stackframe_entry(list : paasmoutput;localsize : longint);
|
|
|
+ procedure tcgppc.g_stackframe_entry(list : taasmoutput;localsize : longint);
|
|
|
begin
|
|
|
case target_os.id of
|
|
|
os_powerpc_macos:
|
|
@@ -379,7 +447,7 @@ const
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.g_stackframe_entry_sysv(list : paasmoutput;localsize : longint);
|
|
|
+ procedure tcgppc.g_stackframe_entry_sysv(list : taasmoutput;localsize : longint);
|
|
|
{ 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 }
|
|
@@ -398,47 +466,47 @@ const
|
|
|
for regcounter := R_3 to R_10 do
|
|
|
a_reg_alloc(list,regcounter);
|
|
|
{ save return address... }
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MFSPR,R_0,R_LR)));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
|
|
{ ... in caller's frame }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER,4))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER,4)));
|
|
|
a_reg_dealloc(list,R_0);
|
|
|
a_reg_alloc(list,R_11);
|
|
|
{ save end of fpr save area }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ORI,R_11,STACK_POINTER,0)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ORI,R_11,STACK_POINTER,0));
|
|
|
a_reg_alloc(list,R_12);
|
|
|
{ 0 or 8 based on SP alignment }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const_const_const(A_RLWINM,
|
|
|
- R_12,STACK_POINTER,0,28,28)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
+ R_12,STACK_POINTER,0,28,28));
|
|
|
{ add in stack length }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_SUBFIC,R_12,R_12,
|
|
|
- -localsize)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_SUBFIC,R_12,R_12,
|
|
|
+ -localsize));
|
|
|
{ establish new alignment }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_reg(A_STWUX,STACK_POINTER,STACK_POINTER,R_12)));
|
|
|
+ list.concat(taicpu.op_reg_reg_reg(A_STWUX,STACK_POINTER,STACK_POINTER,R_12));
|
|
|
a_reg_dealloc(list,R_12);
|
|
|
{ save floating-point registers }
|
|
|
{ !!! has to be optimized: only save registers that are used }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_BL,newasmsymbol('_savefpr_14'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_savefpr_14'),0));
|
|
|
{ compute end of gpr save area }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ADDI,R_11,R_11,-144)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ADDI,R_11,R_11,-144));
|
|
|
{ save gprs and fetch GOT pointer }
|
|
|
{ !!! has to be optimized: only save registers that are used }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_BL,newasmsymbol('_savegpr_14_go'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_savegpr_14_go'),0));
|
|
|
a_reg_alloc(list,R_31);
|
|
|
{ place GOT ptr in r31 }
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MFSPR,R_31,R_LR)));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MFSPR,R_31,R_LR));
|
|
|
{ save the CR if necessary ( !!! always done currently ) }
|
|
|
{ still need to find out where this has to be done for SystemV
|
|
|
a_reg_alloc(list,R_0);
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MFSPR,R_0,R_CR);
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STW,scratch_register,
|
|
|
- new_reference(stack_pointer,LA_CR))));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR);
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STW,scratch_register,
|
|
|
+ new_reference(stack_pointer,LA_CR)));
|
|
|
a_reg_dealloc(list,R_0); }
|
|
|
{ save pointer to incoming arguments }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ADDI,R_30,R_11,144)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ADDI,R_30,R_11,144));
|
|
|
{ now comes the AltiVec context save, not yet implemented !!! }
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.g_stackframe_entry_mac(list : paasmoutput;localsize : longint);
|
|
|
+ procedure tcgppc.g_stackframe_entry_mac(list : taasmoutput;localsize : longint);
|
|
|
{ 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 }
|
|
@@ -457,45 +525,45 @@ const
|
|
|
for regcounter := R_3 to R_10 do
|
|
|
a_reg_alloc(list,regcounter);
|
|
|
{ save return address... }
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MFSPR,R_0,R_LR)));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_LR));
|
|
|
{ ... in caller's frame }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER,8))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STW,R_0,new_reference(STACK_POINTER,8)));
|
|
|
a_reg_dealloc(list,R_0);
|
|
|
{ save floating-point registers }
|
|
|
{ !!! has to be optimized: only save registers that are used }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_BL,newasmsymbol('_savef14'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_savef14'),0));
|
|
|
{ save gprs in gpr save area }
|
|
|
{ !!! has to be optimized: only save registers that are used }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STMW,R_13,new_reference(STACK_POINTER,-220))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STMW,R_13,new_reference(STACK_POINTER,-220)));
|
|
|
{ save the CR if necessary ( !!! always done currently ) }
|
|
|
a_reg_alloc(list,R_0);
|
|
|
- list^.concat(new(paicpu,op_reg_reg(A_MFSPR,R_0,R_CR)));
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STW,R_0,
|
|
|
- new_reference(stack_pointer,LA_CR))));
|
|
|
+ list.concat(taicpu.op_reg_reg(A_MFSPR,R_0,R_CR));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STW,R_0,
|
|
|
+ new_reference(stack_pointer,LA_CR)));
|
|
|
a_reg_dealloc(list,R_0);
|
|
|
{ save pointer to incoming arguments }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ORI,R_31,STACK_POINTER,0)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ORI,R_31,STACK_POINTER,0));
|
|
|
a_reg_alloc(list,R_12);
|
|
|
{ 0 or 8 based on SP alignment }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const_const_const(A_RLWINM,
|
|
|
- R_12,STACK_POINTER,0,28,28)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const_const_const(A_RLWINM,
|
|
|
+ R_12,STACK_POINTER,0,28,28));
|
|
|
{ add in stack length }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_SUBFIC,R_12,R_12,
|
|
|
- -localsize)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_SUBFIC,R_12,R_12,
|
|
|
+ -localsize));
|
|
|
{ establish new alignment }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_reg(A_STWUX,STACK_POINTER,STACK_POINTER,R_12)));
|
|
|
+ list.concat(taicpu.op_reg_reg_reg(A_STWUX,STACK_POINTER,STACK_POINTER,R_12));
|
|
|
a_reg_dealloc(list,R_12);
|
|
|
{ now comes the AltiVec context save, not yet implemented !!! }
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.g_restore_frame_pointer(list : paasmoutput);
|
|
|
+ procedure tcgppc.g_restore_frame_pointer(list : taasmoutput);
|
|
|
|
|
|
begin
|
|
|
{ no frame pointer on the PowerPC (maybe there is one in the SystemV ABI?)}
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.g_return_from_proc(list : paasmoutput;parasize : aword);
|
|
|
+ procedure tcgppc.g_return_from_proc(list : taasmoutput;parasize : aword);
|
|
|
begin
|
|
|
case target_os.id of
|
|
|
os_powerpc_macos:
|
|
@@ -508,7 +576,7 @@ const
|
|
|
end;
|
|
|
|
|
|
|
|
|
- procedure tcgppc.g_return_from_proc_sysv(list : paasmoutput;parasize : aword);
|
|
|
+ procedure tcgppc.g_return_from_proc_sysv(list : taasmoutput;parasize : aword);
|
|
|
|
|
|
var regcounter: TRegister;
|
|
|
|
|
@@ -519,16 +587,16 @@ const
|
|
|
{ AltiVec context restore, not yet implemented !!! }
|
|
|
|
|
|
{ address of gpr save area to r11 }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ADDI,R_11,R_31,-144)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ADDI,R_11,R_31,-144));
|
|
|
{ restore gprs }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_BL,newasmsymbol('_restgpr_14'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_restgpr_14'),0));
|
|
|
{ address of fpr save area to r11 }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ADDI,R_11,R_11,144)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ADDI,R_11,R_11,144));
|
|
|
{ restore fprs and return }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_BL,newasmsymbol('_restfpr_14_x'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_BL,newasmsymbol('_restfpr_14_x'),0));
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.g_return_from_proc_mac(list : paasmoutput;parasize : aword);
|
|
|
+ procedure tcgppc.g_return_from_proc_mac(list : taasmoutput;parasize : aword);
|
|
|
|
|
|
var regcounter: TRegister;
|
|
|
|
|
@@ -539,16 +607,16 @@ const
|
|
|
{ AltiVec context restore, not yet implemented !!! }
|
|
|
|
|
|
{ restore SP }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(A_ORI,STACK_POINTER,R_31,0)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(A_ORI,STACK_POINTER,R_31,0));
|
|
|
{ restore gprs }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LMW,R_13,new_reference(STACK_POINTER,-220))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LMW,R_13,new_reference(STACK_POINTER,-220)));
|
|
|
{ restore return address ... }
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LWZ,R_0,new_reference(STACK_POINTER,8))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LWZ,R_0,new_reference(STACK_POINTER,8)));
|
|
|
{ ... and return from _restf14 }
|
|
|
- list^.concat(new(paicpu,op_sym_ofs(A_B,newasmsymbol('_restf14'),0)));
|
|
|
+ list.concat(taicpu.op_sym_ofs(A_B,newasmsymbol('_restf14'),0));
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_loadaddress_ref_reg(list : paasmoutput;const ref2 : treference;r : tregister);
|
|
|
+ procedure tcgppc.a_loadaddress_ref_reg(list : taasmoutput;const ref2 : treference;r : tregister);
|
|
|
|
|
|
var tmpreg: tregister;
|
|
|
ref, tmpref: treference;
|
|
@@ -566,17 +634,17 @@ const
|
|
|
tmpref.symaddr := refs_ha;
|
|
|
tmpref.is_immediate := true;
|
|
|
if ref.base <> R_NO then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_ref(A_ADDIS,tmpreg,
|
|
|
- ref.base,newreference(tmpref))))
|
|
|
+ list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
|
|
|
+ ref.base,newreference(tmpref)))
|
|
|
else
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LIS,tmpreg,
|
|
|
- newreference(tmpref))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
|
|
|
+ newreference(tmpref)));
|
|
|
ref.base := tmpreg;
|
|
|
ref.symaddr := refs_l;
|
|
|
{ can be folded with one of the next instructions by the }
|
|
|
{ optimizer probably }
|
|
|
- list^.concat(new(paicpu,op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,
|
|
|
- newreference(tmpref))));
|
|
|
+ list.concat(taicpu.op_reg_reg_ref(A_ADDI,tmpreg,tmpreg,
|
|
|
+ newreference(tmpref)));
|
|
|
end;
|
|
|
if ref.offset <> 0 Then
|
|
|
if ref.base <> R_NO then
|
|
@@ -586,8 +654,8 @@ const
|
|
|
else a_load_const_reg(list, OS_32, ref.offset, r)
|
|
|
else
|
|
|
if ref.index <> R_NO Then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_reg(A_ADD,r,ref.base,ref.index)))
|
|
|
- else list^.concat(new(paicpu,op_reg_reg(A_MR,r,ref.base)));
|
|
|
+ list.concat(taicpu.op_reg_reg_reg(A_ADD,r,ref.base,ref.index))
|
|
|
+ else list.concat(taicpu.op_reg_reg(A_MR,r,ref.base));
|
|
|
if assigned(ref.symbol) then
|
|
|
free_scratch_reg(list,tmpreg);
|
|
|
end;
|
|
@@ -595,7 +663,7 @@ const
|
|
|
|
|
|
{ ************* concatcopy ************ }
|
|
|
|
|
|
- procedure tcgppc.g_concatcopy(list : paasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
|
|
|
+ procedure tcgppc.g_concatcopy(list : taasmoutput;const source,dest : treference;len : aword; delsource,loadref : boolean);
|
|
|
|
|
|
var
|
|
|
p: paicpu;
|
|
@@ -641,11 +709,11 @@ const
|
|
|
a_reg_alloc(list,R_0);
|
|
|
getlabel(lab);
|
|
|
a_label(list, lab);
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LWZU,tempreg,
|
|
|
- newreference(src))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LWZU,tempreg,
|
|
|
+ newreference(src)));
|
|
|
a_op_reg_reg_const32(list,A_CMPI,A_NONE,R_CR0,countreg,0);
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_STWU,tempreg,
|
|
|
- newreference(dst))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_STWU,tempreg,
|
|
|
+ newreference(dst)));
|
|
|
a_op_reg_reg_const32(list,A_SUBI,A_NONE,countreg,countreg,1);
|
|
|
a_jmp(list,A_BC,CF_NE,lab);
|
|
|
free_scratch_reg(list,countreg);
|
|
@@ -698,17 +766,17 @@ const
|
|
|
end
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_op_reg_reg_const32(list: paasmoutput; oplo, ophi:
|
|
|
+ procedure tcgppc.a_op_reg_reg_const32(list: taasmoutput; oplo, ophi:
|
|
|
tasmop; reg1, reg2: tregister; a: aword);
|
|
|
|
|
|
begin
|
|
|
if (a and $ffff) <> 0 Then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(OpLo,reg1,reg2,a and $ffff)));
|
|
|
+ list.concat(taicpu.op_reg_reg_const(OpLo,reg1,reg2,a and $ffff));
|
|
|
If (a shr 16) <> 0 Then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_const(OpHi,reg1,reg1,a shr 16)))
|
|
|
+ list.concat(taicpu.op_reg_reg_const(OpHi,reg1,reg1,a shr 16))
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_load_store(list:paasmoutput;op: tasmop;reg:tregister;
|
|
|
+ procedure tcgppc.a_load_store(list:taasmoutput;op: tasmop;reg:tregister;
|
|
|
var ref: treference);
|
|
|
|
|
|
var tmpreg: tregister;
|
|
@@ -723,32 +791,40 @@ const
|
|
|
tmpref.symaddr := refs_ha;
|
|
|
tmpref.is_immediate := true;
|
|
|
if ref.base <> R_NO then
|
|
|
- list^.concat(new(paicpu,op_reg_reg_ref(A_ADDIS,tmpreg,
|
|
|
- ref.base,newreference(tmpref))))
|
|
|
+ list.concat(taicpu.op_reg_reg_ref(A_ADDIS,tmpreg,
|
|
|
+ ref.base,newreference(tmpref)))
|
|
|
else
|
|
|
- list^.concat(new(paicpu,op_reg_ref(A_LIS,tmpreg,
|
|
|
- newreference(tmpref))));
|
|
|
+ list.concat(taicpu.op_reg_ref(A_LIS,tmpreg,
|
|
|
+ newreference(tmpref)));
|
|
|
ref.base := tmpreg;
|
|
|
ref.symaddr := refs_l;
|
|
|
end;
|
|
|
- list^.concat(new(paicpu,op_reg_ref(op,reg,newreference(ref))));
|
|
|
+ list.concat(taicpu.op_reg_ref(op,reg,newreference(ref)));
|
|
|
if assigned(ref.symbol) then
|
|
|
free_scratch_reg(list,tmpreg);
|
|
|
end;
|
|
|
|
|
|
- procedure tcgppc.a_jmp(list: paasmoutput; op: tasmop; c: tasmcondflags;
|
|
|
+ procedure tcgppc.a_jmp(list: taasmoutput; op: tasmop; c: tasmcondflags;
|
|
|
l: pasmlabel);
|
|
|
var p: paicpu;
|
|
|
begin
|
|
|
- p := new(paicpu,op_sym(op,newasmsymbol(l^.name)));
|
|
|
+ p := taicpu.op_sym(op,newasmsymbol(l^.name));
|
|
|
create_cond_norm(c,0,p^.condition);
|
|
|
- list^.concat(p)
|
|
|
+ list.concat(p)
|
|
|
end;
|
|
|
|
|
|
end.
|
|
|
{
|
|
|
$Log$
|
|
|
- Revision 1.2 2001-09-05 20:21:03 jonas
|
|
|
+ Revision 1.3 2001-09-06 15:25:55 jonas
|
|
|
+ * changed type of tcg from object to class -> abstract methods are now
|
|
|
+ a lot cleaner :)
|
|
|
+ + more updates: load_*_loc methods, op_*_* methods, g_flags2reg method
|
|
|
+ (if possible with geenric implementation and necessary ppc
|
|
|
+ implementations)
|
|
|
+ * worked a bit further on cgflw, now working on exitnode
|
|
|
+
|
|
|
+ Revision 1.2 2001/09/05 20:21:03 jonas
|
|
|
* new cgflow based on n386flw with all nodes until forn "translated"
|
|
|
+ a_cmp_loc_*_label methods for tcg
|
|
|
+ base implementatino for a_cmp_ref_*_label methods
|