mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 21:59:47 +02:00
* Patch from Fuxin Zhang: other mips and mipsel CPUs changes
git-svn-id: trunk@21538 -
This commit is contained in:
parent
22eae1b337
commit
93e0dd9c2f
@ -195,12 +195,7 @@ end;
|
||||
constructor taicpu.op_sym(op: tasmop; _op1: tasmsymbol);
|
||||
begin
|
||||
inherited Create(op);
|
||||
is_jmp := op in [A_J, A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI,
|
||||
A_BLTUI, A_BLEUI, A_BGTUI, A_BGEUI,
|
||||
A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE,
|
||||
A_BLTU, A_BLEU, A_BGTU, A_BGEU
|
||||
];
|
||||
|
||||
is_jmp := op in [A_BC, A_BA];
|
||||
ops := 1;
|
||||
loadsymbol(0, _op1, 0);
|
||||
end;
|
||||
@ -208,10 +203,7 @@ end;
|
||||
constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
|
||||
begin
|
||||
inherited create(op);
|
||||
is_jmp := op in [A_J,
|
||||
A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
|
||||
A_BGTUI, A_BGEUI,
|
||||
A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU];
|
||||
is_jmp := op in [A_BC, A_BA];
|
||||
ops := 3;
|
||||
loadreg(0, _op1);
|
||||
loadreg(1, _op2);
|
||||
@ -221,10 +213,7 @@ end;
|
||||
constructor taicpu.op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol);
|
||||
begin
|
||||
inherited create(op);
|
||||
is_jmp := op in [A_J,
|
||||
A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
|
||||
A_BGTUI, A_BGEUI,
|
||||
A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU, A_BGTZ];
|
||||
is_jmp := op in [A_BC, A_BA];
|
||||
ops := 2;
|
||||
loadreg(0, _op1);
|
||||
loadsymbol(1, _op2, 0);
|
||||
|
@ -93,8 +93,8 @@ Const
|
||||
|
||||
StoreDst = 1;
|
||||
|
||||
aopt_uncondjmp = A_J;
|
||||
aopt_condjmp = A_BEQ;
|
||||
aopt_uncondjmp = A_BA;
|
||||
aopt_condjmp = A_BC;
|
||||
|
||||
Implementation
|
||||
|
||||
|
@ -27,7 +27,7 @@ interface
|
||||
|
||||
uses
|
||||
globtype, parabase,
|
||||
cgbase, cgutils, cgobj, cg64f32,
|
||||
cgbase, cgutils, cgobj, cg64f32, cpupara,
|
||||
aasmbase, aasmtai, aasmcpu, aasmdata,
|
||||
cpubase, cpuinfo,
|
||||
node, symconst, SymType, symdef,
|
||||
@ -36,6 +36,7 @@ uses
|
||||
type
|
||||
TCGMIPS = class(tcg)
|
||||
public
|
||||
|
||||
procedure init_register_allocators; override;
|
||||
procedure done_register_allocators; override;
|
||||
function getfpuregister(list: tasmlist; size: Tcgsize): Tregister; override;
|
||||
@ -106,6 +107,11 @@ type
|
||||
|
||||
procedure create_codegen;
|
||||
|
||||
const
|
||||
TOpCmp2AsmCond : array[topcmp] of TAsmCond=(C_NONE,
|
||||
C_EQ,C_GT,C_LT,C_GE,C_LE,C_NE,C_LEU,C_LTU,C_GEU,C_GTU
|
||||
);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -311,7 +317,7 @@ begin
|
||||
if (cs_create_pic in current_settings.moduleswitches) and
|
||||
assigned(ref.symbol) then
|
||||
begin
|
||||
tmpreg := GetIntRegister(list, OS_INT);
|
||||
tmpreg := cg.GetIntRegister(list, OS_INT);
|
||||
reference_reset(tmpref,sizeof(aint));
|
||||
tmpref.symbol := ref.symbol;
|
||||
tmpref.refaddr := addr_pic;
|
||||
@ -518,12 +524,18 @@ begin
|
||||
RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25],
|
||||
first_int_imreg, []);
|
||||
|
||||
{
|
||||
rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS,
|
||||
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,
|
||||
RS_F8,RS_F9,RS_F10,RS_F11,RS_F12,RS_F13,RS_F14,RS_F15,
|
||||
RS_F16,RS_F17,RS_F18,RS_F19,RS_F20,RS_F21,RS_F22,RS_F23,
|
||||
RS_F24,RS_F25,RS_F26,RS_F27,RS_F28,RS_F29,RS_F30,RS_F31],
|
||||
first_fpu_imreg, []);
|
||||
}
|
||||
rg[R_FPUREGISTER] := trgcpu.Create(R_FPUREGISTER, R_SUBFS,
|
||||
[RS_F0,RS_F2,RS_F4,RS_F6, RS_F8,RS_F10,RS_F12,RS_F14,
|
||||
RS_F16,RS_F18,RS_F20,RS_F22, RS_F24,RS_F26,RS_F28,RS_F30],
|
||||
first_fpu_imreg, []);
|
||||
|
||||
{ needs at least one element for rgobj not to crash }
|
||||
rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
|
||||
@ -1235,6 +1247,7 @@ end;
|
||||
procedure TCGMIPS.a_cmp_const_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; a: tcgint; reg: tregister; l: tasmlabel);
|
||||
var
|
||||
tmpreg: tregister;
|
||||
ai : Taicpu;
|
||||
begin
|
||||
if a = 0 then
|
||||
tmpreg := NR_R0
|
||||
@ -1243,75 +1256,37 @@ begin
|
||||
tmpreg := GetIntRegister(list, OS_INT);
|
||||
list.concat(taicpu.op_reg_const(A_LI, tmpreg, a));
|
||||
end;
|
||||
case cmp_op of
|
||||
OC_EQ: { equality comparison }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg, tmpreg, l));
|
||||
OC_GT: { greater than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGT, reg, tmpreg, l));
|
||||
OC_LT: { less than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLT, reg, tmpreg, l));
|
||||
OC_GTE: { greater or equal than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGE, reg, tmpreg, l));
|
||||
OC_LTE: { less or equal than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLE, reg, tmpreg, l));
|
||||
OC_NE: { not equal }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BNE, reg, tmpreg, l));
|
||||
OC_BE: { less or equal than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg, tmpreg, l));
|
||||
OC_B: { less than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg, tmpreg, l));
|
||||
OC_AE: { greater or equal than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg, tmpreg, l));
|
||||
OC_A: { greater than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg, tmpreg, l));
|
||||
else
|
||||
internalerror(200701071);
|
||||
end;
|
||||
ai := taicpu.op_reg_reg_sym(A_BC, reg, tmpreg, l);
|
||||
ai.SetCondition(TOpCmp2AsmCond[cmp_op]);
|
||||
list.concat(ai);
|
||||
list.Concat(TAiCpu.Op_none(A_NOP));
|
||||
end;
|
||||
|
||||
|
||||
procedure TCGMIPS.a_cmp_reg_reg_label(list: tasmlist; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);
|
||||
var
|
||||
ai : Taicpu;
|
||||
begin
|
||||
case cmp_op of
|
||||
OC_EQ: { equality comparison }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BEQ, reg2, reg1, l));
|
||||
OC_GT: { greater than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGT, reg2, reg1, l));
|
||||
OC_LT: { less than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLT, reg2, reg1, l));
|
||||
OC_GTE: { greater or equal than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGE, reg2, reg1, l));
|
||||
OC_LTE: { less or equal than (signed) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLE, reg2, reg1, l));
|
||||
OC_NE: { not equal }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BNE, reg2, reg1, l));
|
||||
OC_BE: { less or equal than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLEU, reg2, reg1, l));
|
||||
OC_B: { less than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BLTU, reg2, reg1, l));
|
||||
OC_AE: { greater or equal than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGEU, reg2, reg1, l));
|
||||
OC_A: { greater than (unsigned) }
|
||||
list.concat(taicpu.op_reg_reg_sym(A_BGTU, reg2, reg1, l));
|
||||
else
|
||||
internalerror(200701072);
|
||||
end;{ case }
|
||||
ai := taicpu.op_reg_reg_sym(A_BC, reg2, reg1, l);
|
||||
ai.SetCondition(TOpCmp2AsmCond[cmp_op]);
|
||||
list.concat(ai);
|
||||
list.Concat(TAiCpu.Op_none(A_NOP));
|
||||
end;
|
||||
|
||||
|
||||
procedure TCGMIPS.a_jmp_always(List: tasmlist; l: TAsmLabel);
|
||||
var
|
||||
ai : Taicpu;
|
||||
begin
|
||||
List.Concat(TAiCpu.op_sym(A_J,l));
|
||||
{ Delay slot }
|
||||
ai := taicpu.op_sym(A_BA, l);
|
||||
list.concat(ai);
|
||||
list.Concat(TAiCpu.Op_none(A_NOP));
|
||||
end;
|
||||
|
||||
|
||||
procedure TCGMIPS.a_jmp_name(list: tasmlist; const s: string);
|
||||
begin
|
||||
List.Concat(TAiCpu.op_sym(A_J, current_asmdata.RefAsmSymbol(s)));
|
||||
List.Concat(TAiCpu.op_sym(A_BA, current_asmdata.RefAsmSymbol(s)));
|
||||
{ Delay slot }
|
||||
list.Concat(TAiCpu.Op_none(A_NOP));
|
||||
end;
|
||||
@ -1341,6 +1316,8 @@ procedure TCGMIPS.g_proc_entry(list: tasmlist; localsize: longint; nostackframe:
|
||||
var
|
||||
lastintoffset,lastfpuoffset,
|
||||
nextoffset : aint;
|
||||
i : longint;
|
||||
ra_save,framesave : taicpu;
|
||||
fmask,mask : dword;
|
||||
saveregs : tcpuregisterset;
|
||||
href: treference;
|
||||
@ -1348,14 +1325,8 @@ var
|
||||
reg : Tsuperregister;
|
||||
helplist : TAsmList;
|
||||
begin
|
||||
{
|
||||
if STK2_dummy <> 0 then
|
||||
begin
|
||||
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, -STK2_dummy));
|
||||
end;
|
||||
}
|
||||
a_reg_alloc(list,NR_STACK_POINTER_REG);
|
||||
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
// if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
a_reg_alloc(list,NR_FRAME_POINTER_REG);
|
||||
|
||||
if nostackframe then
|
||||
@ -1368,9 +1339,7 @@ begin
|
||||
{ if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
list.concat(Taicpu.Op_reg_reg_const(A_P_SW, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG, -LocalSize));
|
||||
}
|
||||
{ if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
list.concat(Taicpu.op_reg_reg(A_MOVE, NR_FRAME_POINTER_REG, NR_STACK_POINTER_REG));
|
||||
}
|
||||
|
||||
|
||||
reference_reset(href,0);
|
||||
href.base:=NR_STACK_POINTER_REG;
|
||||
@ -1397,7 +1366,11 @@ begin
|
||||
nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
|
||||
saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
|
||||
include(saveregs,RS_R31);
|
||||
//if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
include(saveregs,RS_FRAME_POINTER_REG);
|
||||
lastintoffset:=LocalSize;
|
||||
framesave:=nil;
|
||||
|
||||
for reg:=RS_R1 to RS_R31 do
|
||||
begin
|
||||
if reg in saveregs then
|
||||
@ -1406,24 +1379,67 @@ begin
|
||||
mask:=mask or (1 shl ord(reg));
|
||||
href.offset:=nextoffset;
|
||||
lastintoffset:=nextoffset;
|
||||
helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
|
||||
if (reg=RS_FRAME_POINTER_REG) then
|
||||
framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
|
||||
else if (reg=RS_R31) then
|
||||
ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
|
||||
else
|
||||
helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
|
||||
inc(nextoffset,4);
|
||||
end;
|
||||
end;
|
||||
|
||||
//list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,current_procinfo.para_stack_size));
|
||||
list.concat(Taicpu.op_none(A_P_SET_NOMIPS16));
|
||||
list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
|
||||
list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,NR_STACK_POINTER_REG,LocalSize,NR_R31));
|
||||
list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
|
||||
list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
|
||||
list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
|
||||
list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
|
||||
|
||||
if (-LocalSize >= simm16lo) and (-LocalSize <= simm16hi) then
|
||||
list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize))
|
||||
begin
|
||||
list.concat(Taicpu.Op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-LocalSize));
|
||||
list.concat(ra_save);
|
||||
//if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
begin
|
||||
list.concat(framesave);
|
||||
list.concat(Taicpu.op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,
|
||||
NR_STACK_POINTER_REG,LocalSize));
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.concat(Taicpu.Op_reg_const(A_LI,NR_R3,-LocalSize));
|
||||
list.concat(Taicpu.Op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R3));
|
||||
list.concat(ra_save);
|
||||
//if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
begin
|
||||
list.concat(framesave);
|
||||
list.concat(Taicpu.op_reg_reg_reg(A_SUB,NR_FRAME_POINTER_REG,
|
||||
NR_STACK_POINTER_REG,NR_R3));
|
||||
end;
|
||||
end;
|
||||
|
||||
with TMIPSProcInfo(current_procinfo) do
|
||||
begin
|
||||
href.offset:=0;
|
||||
//if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
href.base:=NR_FRAME_POINTER_REG;
|
||||
|
||||
for i:=0 to MIPS_MAX_REGISTERS_USED_IN_CALL-1 do
|
||||
if (register_used[i]) then
|
||||
begin
|
||||
reg:=parainsupregs[i];
|
||||
if register_offset[i]=-1 then
|
||||
comment(V_warning,'Register parameter has offset -1 in TCGMIPS.g_proc_entry');
|
||||
|
||||
//if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
// href.offset:=register_offset[i]+Localsize
|
||||
//else
|
||||
href.offset:=register_offset[i];
|
||||
list.concat(taicpu.op_reg_ref(A_SW, newreg(R_INTREGISTER,reg,R_SUBWHOLE), href));
|
||||
end;
|
||||
end;
|
||||
|
||||
if (cs_create_pic in current_settings.moduleswitches) and
|
||||
@ -1447,9 +1463,6 @@ begin
|
||||
stacksize:=current_procinfo.calc_stackframe_size;
|
||||
if nostackframe then
|
||||
begin
|
||||
{ if STK2_dummy <> 0 then
|
||||
list.concat(Taicpu.Op_reg_reg_const(A_P_STK2, STK2_PTR, STK2_PTR, STK2_dummy));
|
||||
}
|
||||
list.concat(taicpu.op_reg(A_J, NR_R31));
|
||||
list.concat(Taicpu.op_none(A_NOP));
|
||||
list.concat(Taicpu.op_none(A_P_SET_MACRO));
|
||||
@ -1474,12 +1487,14 @@ begin
|
||||
nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
|
||||
saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
|
||||
include(saveregs,RS_R31);
|
||||
//if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
|
||||
include(saveregs,RS_FRAME_POINTER_REG);
|
||||
for reg:=RS_R1 to RS_R31 do
|
||||
begin
|
||||
if reg in saveregs then
|
||||
begin
|
||||
href.offset:=nextoffset;
|
||||
list.concat(taicpu.op_reg_ref(A_LD,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
|
||||
list.concat(taicpu.op_reg_ref(A_LW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
|
||||
inc(nextoffset,sizeof(aint));
|
||||
end;
|
||||
end;
|
||||
@ -1539,6 +1554,7 @@ var
|
||||
src, dst: TReference;
|
||||
lab: tasmlabel;
|
||||
Count, count2: aint;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
if len > high(longint) then
|
||||
internalerror(2002072704);
|
||||
@ -1575,7 +1591,10 @@ begin
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 4));
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 4));
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1));
|
||||
list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
|
||||
//list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
|
||||
ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab);
|
||||
ai.setcondition(C_GT);
|
||||
list.concat(ai);
|
||||
list.concat(taicpu.op_none(A_NOP));
|
||||
len := len mod 4;
|
||||
end;
|
||||
@ -1626,6 +1645,7 @@ var
|
||||
tmpreg1, countreg: TRegister;
|
||||
i: aint;
|
||||
lab: tasmlabel;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
if len > 31 then
|
||||
g_concatcopy_move(list, Source, dest, len)
|
||||
@ -1646,8 +1666,8 @@ begin
|
||||
{ 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 }
|
||||
countreg := GetIntRegister(list, OS_INT);
|
||||
tmpreg1 := GetIntRegister(list, OS_INT);
|
||||
countreg := cg.GetIntRegister(list, OS_INT);
|
||||
tmpreg1 := cg.GetIntRegister(list, OS_INT);
|
||||
a_load_const_reg(list, OS_INT, len, countreg);
|
||||
{ explicitely allocate R_O0 since it can be used safely here }
|
||||
{ (for holding date that's being copied) }
|
||||
@ -1658,13 +1678,16 @@ begin
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, src.base, src.base, 1));
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, dst.base, dst.base, 1));
|
||||
list.concat(taicpu.op_reg_reg_const(A_ADDIU, countreg, countreg, -1));
|
||||
list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
|
||||
//list.concat(taicpu.op_reg_sym(A_BGTZ, countreg, lab));
|
||||
ai := taicpu.op_reg_reg_sym(A_BC,countreg, NR_R0, lab);
|
||||
ai.setcondition(C_GT);
|
||||
list.concat(ai);
|
||||
list.concat(taicpu.op_none(A_NOP));
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ unrolled loop }
|
||||
tmpreg1 := GetIntRegister(list, OS_INT);
|
||||
tmpreg1 := cg.GetIntRegister(list, OS_INT);
|
||||
for i := 1 to len do
|
||||
begin
|
||||
list.concat(taicpu.op_reg_ref(A_LBU, tmpreg1, src));
|
||||
@ -1679,25 +1702,25 @@ end;
|
||||
|
||||
procedure TCGMIPS.g_intf_wrapper(list: tasmlist; procdef: tprocdef; const labelname: string; ioffset: longint);
|
||||
|
||||
procedure loadvmttor24;
|
||||
procedure loadvmttor25;
|
||||
var
|
||||
href: treference;
|
||||
begin
|
||||
reference_reset_base(href, NR_R2, 0, sizeof(aint)); { return value }
|
||||
cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24);
|
||||
cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
|
||||
end;
|
||||
|
||||
|
||||
procedure op_onr24methodaddr;
|
||||
procedure op_onr25methodaddr;
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
if (procdef.extnumber=$ffff) then
|
||||
Internalerror(200006139);
|
||||
{ call/jmp vmtoffs(%eax) ; method offs }
|
||||
reference_reset_base(href, NR_R24, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
|
||||
cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R24);
|
||||
list.concat(taicpu.op_reg(A_JR, NR_R24));
|
||||
reference_reset_base(href, NR_R25, tobjectdef(procdef.struct).vmtmethodoffset(procdef.extnumber), sizeof(aint));
|
||||
cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_R25);
|
||||
list.concat(taicpu.op_reg(A_JR, NR_R25));
|
||||
end;
|
||||
var
|
||||
make_global: boolean;
|
||||
@ -1728,8 +1751,8 @@ begin
|
||||
if (po_virtualmethod in procdef.procoptions) and
|
||||
not is_objectpascal_helper(procdef.struct) then
|
||||
begin
|
||||
loadvmttor24;
|
||||
op_onr24methodaddr;
|
||||
loadvmttor25;
|
||||
op_onr25methodaddr;
|
||||
end
|
||||
else
|
||||
list.concat(taicpu.op_sym(A_J,current_asmdata.RefAsmSymbol(procdef.mangledname)));
|
||||
@ -1790,26 +1813,21 @@ begin
|
||||
a_load64_reg_cgpara(list, hreg64, paraloc);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
procedure TCg64MPSel.a_op64_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; regsrc, regdst: TRegister64);
|
||||
var
|
||||
op1, op2, op_call64: TAsmOp;
|
||||
tmpreg1, tmpreg2: TRegister;
|
||||
begin
|
||||
tmpreg1 := NR_TCR12; //GetIntRegister(list, OS_INT);
|
||||
tmpreg2 := NR_TCR13; //GetIntRegister(list, OS_INT);
|
||||
tmpreg1 := cg.GetIntRegister(list, OS_INT);
|
||||
tmpreg2 := cg.GetIntRegister(list, OS_INT);
|
||||
|
||||
case op of
|
||||
OP_ADD:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc.reglo, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc.reghi, regdst.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, NR_TCR10, NR_TCR10, tmpreg2));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, tmpreg1, tmpreg2));
|
||||
exit;
|
||||
end;
|
||||
OP_AND:
|
||||
@ -1822,10 +1840,10 @@ begin
|
||||
OP_NEG:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, NR_R0, regsrc.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, NR_R0, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, NR_R0, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, NR_R0, regsrc.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, NR_TCR10, regdst.reghi, NR_TCR10));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
|
||||
exit;
|
||||
end;
|
||||
OP_NOT:
|
||||
@ -1843,11 +1861,10 @@ begin
|
||||
OP_SUB:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reglo, regsrc.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regdst.reglo, tmpreg1));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regdst.reghi, regsrc.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, tmpreg2, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, regdst.reglo, tmpreg1));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, regsrc.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg2));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg2));
|
||||
exit;
|
||||
end;
|
||||
OP_XOR:
|
||||
@ -1860,26 +1877,14 @@ begin
|
||||
internalerror(200306017);
|
||||
|
||||
end; {case}
|
||||
|
||||
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure TCg64MPSel.a_op64_const_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regdst: TRegister64);
|
||||
var
|
||||
op1, op2: TAsmOp;
|
||||
begin
|
||||
case op of
|
||||
OP_NEG,
|
||||
OP_NOT:
|
||||
internalerror(200306017);
|
||||
end;
|
||||
a_op64_const_reg_reg(list, op, size, value, regdst, regdst);
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure TCg64MPSel.a_op64_const_reg_reg(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64);
|
||||
var
|
||||
l: tlocation;
|
||||
@ -1898,59 +1903,15 @@ end;
|
||||
|
||||
procedure TCg64MPSel.a_op64_const_reg_reg_checkoverflow(list: tasmlist; op: TOpCG; size: tcgsize; Value: int64; regsrc, regdst: tregister64; setflags: boolean; var ovloc: tlocation);
|
||||
var
|
||||
op1, op2: TAsmOp;
|
||||
tmpreg1: TRegister;
|
||||
tmpreg64: TRegister64;
|
||||
begin
|
||||
tmpreg1 := NR_TCR12;
|
||||
case op of
|
||||
OP_NEG,
|
||||
OP_NOT:
|
||||
internalerror(200306017);
|
||||
end;
|
||||
tmpreg64.reglo := cg.GetIntRegister(list, OS_S32);
|
||||
tmpreg64.reghi := cg.GetIntRegister(list, OS_S32);
|
||||
|
||||
list.concat(taicpu.op_reg_const(A_LI, NR_TCR10, aint(hi(Value))));
|
||||
list.concat(taicpu.op_reg_const(A_LI, NR_TCR11, aint(lo(Value))));
|
||||
case op of
|
||||
OP_ADD:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc.reglo, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc.reghi, NR_TCR11));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, tmpreg1, regdst.reghi));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
|
||||
exit;
|
||||
end;
|
||||
OP_AND:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reglo, regsrc.reglo, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_AND, regdst.reghi, regsrc.reghi, NR_TCR11));
|
||||
exit;
|
||||
end;
|
||||
list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reglo, aint(lo(Value))));
|
||||
list.concat(taicpu.op_reg_const(A_LI, tmpreg64.reghi, aint(hi(Value))));
|
||||
|
||||
OP_OR:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reglo, regsrc.reglo, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_OR, regdst.reghi, regsrc.reghi, NR_TCR11));
|
||||
exit;
|
||||
end;
|
||||
OP_SUB:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc.reglo, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc.reglo, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc.reghi, NR_TCR11));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regdst.reghi, tmpreg1));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reghi, tmpreg1));
|
||||
exit;
|
||||
end;
|
||||
OP_XOR:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reglo, regsrc.reglo, NR_TCR10));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_XOR, regdst.reghi, regsrc.reghi, NR_TCR11));
|
||||
exit;
|
||||
end;
|
||||
else
|
||||
internalerror(200306017);
|
||||
end;
|
||||
a_op64_reg_reg_reg_checkoverflow(list, op, size, tmpreg64, regsrc, regdst, False, ovloc);
|
||||
|
||||
end;
|
||||
|
||||
@ -1961,22 +1922,15 @@ var
|
||||
tmpreg1, tmpreg2: TRegister;
|
||||
|
||||
begin
|
||||
tmpreg1 := NR_TCR12;
|
||||
tmpreg2 := NR_TCR13;
|
||||
|
||||
case op of
|
||||
OP_NEG,
|
||||
OP_NOT:
|
||||
internalerror(200306017);
|
||||
end;
|
||||
case op of
|
||||
OP_ADD:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg1, regsrc2.reglo, regsrc1.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, tmpreg1, regsrc2.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, tmpreg2, regsrc2.reghi, regsrc1.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, NR_TCR10, tmpreg2));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
|
||||
tmpreg1 := cg.GetIntRegister(list,OS_S32);
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reglo, regsrc2.reglo, regsrc1.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regdst.reglo, regsrc2.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_ADDU, regdst.reghi, regdst.reghi, tmpreg1));
|
||||
exit;
|
||||
end;
|
||||
OP_AND:
|
||||
@ -1993,11 +1947,11 @@ begin
|
||||
end;
|
||||
OP_SUB:
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg1, regsrc2.reglo, regsrc1.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR10, regsrc2.reglo, tmpreg1));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, tmpreg2, regsrc2.reghi, regsrc1.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, tmpreg2, NR_TCR10));
|
||||
list.concat(Taicpu.Op_reg_reg(A_MOVE, regdst.reglo, tmpreg1));
|
||||
tmpreg1 := cg.GetIntRegister(list,OS_S32);
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reglo, regsrc2.reglo, regsrc1.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg1, regsrc2.reglo, regdst.reglo));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regsrc2.reghi, regsrc1.reghi));
|
||||
list.concat(taicpu.op_reg_reg_reg(A_SUBU, regdst.reghi, regdst.reghi, tmpreg1));
|
||||
exit;
|
||||
end;
|
||||
OP_XOR:
|
||||
|
@ -181,7 +181,6 @@ unit cpubase;
|
||||
Generic Register names
|
||||
*****************************************************************************}
|
||||
|
||||
STK2_PTR = NR_R23;
|
||||
NR_GP = NR_R28;
|
||||
NR_SP = NR_R29;
|
||||
NR_S8 = NR_R30;
|
||||
@ -228,14 +227,6 @@ unit cpubase;
|
||||
NR_FPU_RESULT_REG = NR_F0;
|
||||
NR_MM_RESULT_REG = NR_NO;
|
||||
|
||||
NR_TCR0 = NR_R15;
|
||||
NR_TCR1 = NR_R3;
|
||||
|
||||
NR_TCR10 = NR_R20;
|
||||
NR_TCR11 = NR_R21;
|
||||
NR_TCR12 = NR_R18;
|
||||
NR_TCR13 = NR_R19;
|
||||
|
||||
|
||||
{*****************************************************************************
|
||||
GCC /ABI linking information
|
||||
@ -287,10 +278,6 @@ unit cpubase;
|
||||
function std_regnum_search(const s:string):Tregister;
|
||||
function std_regname(r:Tregister):string;
|
||||
|
||||
var
|
||||
STK2_dummy: aint;
|
||||
STK2_Localsize: aint;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -342,27 +329,25 @@ unit cpubase;
|
||||
begin
|
||||
{ This isn't 100% perfect because the arm allows jumps also by writing to PC=R15.
|
||||
To overcome this problem we simply forbid that FPC generates jumps by loading R15 }
|
||||
is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR,
|
||||
A_BEQ,A_BNE,A_BGEZ,A_BGEZAL,A_BGTZ,A_BLEZ,A_BLTZ,A_BLTZAL,
|
||||
A_BEQL,A_BGEZALL,A_BGEZL,A_BGTZL,A_BLEZL,A_BLTZALL,A_BLTZL,A_BNEL];
|
||||
is_calljmp:= o in [A_J,A_JAL,A_JALR,{ A_JALX, }A_JR, A_BA, A_BC, A_BC1T, A_BC1F];
|
||||
end;
|
||||
|
||||
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
const
|
||||
inverse: array[TAsmCond] of TAsmCond=(C_None,
|
||||
C_EQ, C_NE, C_LT, C_LE, C_GT, C_GE, C_LTU, C_LEU, C_GTU, C_GEU,
|
||||
C_FEQ, {Equal}
|
||||
C_FNE, {Not Equal}
|
||||
C_FGT, {Greater}
|
||||
C_FLT, {Less}
|
||||
C_FGE, {Greater or Equal}
|
||||
C_FLE {Less or Equal}
|
||||
|
||||
C_NE, C_EQ, C_GE, C_GT, C_LE, C_LT, C_GEU, C_GTU, C_LEU, C_LTU,
|
||||
C_FNE,
|
||||
C_FEQ,
|
||||
C_FLE,
|
||||
C_FGE,
|
||||
C_FLT,
|
||||
C_FGT
|
||||
);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end; function findreg_by_number(r:Tregister):tregisterindex;
|
||||
end;
|
||||
function findreg_by_number(r:Tregister):tregisterindex;
|
||||
begin
|
||||
result:=rgBase.findreg_by_number_table(r,regnumber_index);
|
||||
end;
|
||||
@ -393,6 +378,4 @@ unit cpubase;
|
||||
|
||||
|
||||
begin
|
||||
STK2_dummy := 10;
|
||||
STK2_Localsize := 0;
|
||||
end.
|
||||
|
@ -150,6 +150,27 @@ unit cpugas;
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
function getnextfpreg(tmpfpu : shortstring) : shortstring;
|
||||
begin
|
||||
case length(tmpfpu) of
|
||||
3:
|
||||
if (tmpfpu[3] = '9') then
|
||||
tmpfpu:='$f10'
|
||||
else
|
||||
tmpfpu[3] := succ(tmpfpu[3]);
|
||||
4:
|
||||
if (tmpfpu[4] = '9') then
|
||||
tmpfpu:='$f20'
|
||||
else
|
||||
tmpfpu[4] := succ(tmpfpu[4]);
|
||||
else
|
||||
internalerror(20120531);
|
||||
end;
|
||||
getnextfpreg := tmpfpu;
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
procedure TMIPSInstrWriter.WriteInstruction(hp: Tai);
|
||||
var
|
||||
@ -158,23 +179,13 @@ unit cpugas;
|
||||
i: integer;
|
||||
tmpfpu: string;
|
||||
tmpfpu_len: longint;
|
||||
r: TRegister;
|
||||
begin
|
||||
if hp.typ <> ait_instruction then
|
||||
exit;
|
||||
op := taicpu(hp).opcode;
|
||||
|
||||
case op of
|
||||
A_P_STK2:
|
||||
begin
|
||||
s1 := getopstr(taicpu(hp).oper[2]^);
|
||||
STK2_LocalSize := align(STK2_LocalSize, 8);
|
||||
if s1[1] = '-' then
|
||||
str(-STK2_LocalSize, s1)
|
||||
else
|
||||
str(STK2_LocalSize, s1);
|
||||
s := #9 + gas_op2str[A_ADDIU] + #9 + getopstr(taicpu(hp).oper[0]^)+ ',' + getopstr(taicpu(hp).oper[1]^) + ',' + s1;
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
A_P_SET_NOMIPS16:
|
||||
begin
|
||||
s := #9 + '.set' + #9 + 'nomips16';
|
||||
@ -222,8 +233,14 @@ unit cpugas;
|
||||
s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
|
||||
owner.AsmWriteLn(s);
|
||||
|
||||
{ bug if $f9/$f19
|
||||
tmpfpu_len := length(tmpfpu);
|
||||
tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
|
||||
|
||||
}
|
||||
r := taicpu(hp).oper[0]^.reg;
|
||||
setsupreg(r, getsupreg(r) + 1);
|
||||
tmpfpu := gas_regname(r);
|
||||
s := #9 + gas_op2str[A_LWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); // + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
@ -233,8 +250,13 @@ unit cpugas;
|
||||
s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
|
||||
owner.AsmWriteLn(s);
|
||||
|
||||
{
|
||||
tmpfpu_len := length(tmpfpu);
|
||||
tmpfpu[tmpfpu_len] := succ(tmpfpu[tmpfpu_len]);
|
||||
}
|
||||
r := taicpu(hp).oper[0]^.reg;
|
||||
setsupreg(r, getsupreg(r) + 1);
|
||||
tmpfpu := gas_regname(r);
|
||||
s := #9 + gas_op2str[A_SWC1] + #9 + tmpfpu + ',' + getopstr_4(taicpu(hp).oper[1]^); //+ ',' + getopstr(taicpu(hp).oper[2]^) + '(' + getopstr(taicpu(hp).oper[1]^) + ')';
|
||||
owner.AsmWriteLn(s);
|
||||
end;
|
||||
|
@ -137,145 +137,216 @@ end;
|
||||
function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4: tasmlabel;
|
||||
tmpreg : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
//current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_eq := NR_TCR10;
|
||||
cmp64_eq := tmpreg;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4: tasmlabel;
|
||||
tmpreg : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 1));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
//current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_sym(A_BNE, left_reg.reglo, right_reg.reglo, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reglo, right_reg.reglo, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg, 0));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_ne := NR_TCR10;
|
||||
cmp64_ne := tmpreg;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
||||
tmpreg1,tmpreg2 : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
|
||||
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
current_asmdata.getjumplabel(lfcmp64_L5);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, NR_TCR11, left_reg.reghi, right_reg.reghi));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, left_reg.reghi, right_reg.reghi));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reglo, right_reg.reglo));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_lt := NR_TCR10;
|
||||
cmp64_lt := tmpreg1;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
||||
tmpreg1,tmpreg2 : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
|
||||
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
current_asmdata.getjumplabel(lfcmp64_L5);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, NR_TCR11, right_reg.reghi, left_reg.reghi));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLT, tmpreg2, right_reg.reghi, left_reg.reghi));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reglo, left_reg.reglo));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_le := NR_TCR10;
|
||||
cmp64_le := tmpreg1;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
||||
tmpreg1,tmpreg2 : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
|
||||
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
current_asmdata.getjumplabel(lfcmp64_L5);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reghi, right_reg.reghi));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reghi, right_reg.reghi));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, left_reg.reghi, right_reg.reghi, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, left_reg.reghi, right_reg.reghi, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, left_reg.reglo, right_reg.reglo));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L5));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, left_reg.reglo, right_reg.reglo));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BA, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_ltu := NR_TCR10;
|
||||
cmp64_ltu := tmpreg1;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
|
||||
var
|
||||
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
||||
tmpreg1,tmpreg2 : TRegister;
|
||||
ai : TaiCpu;
|
||||
begin
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
||||
tmpreg1 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
tmpreg2 := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 0));
|
||||
|
||||
current_asmdata.getjumplabel(lfcmp64_L4);
|
||||
current_asmdata.getjumplabel(lfcmp64_L5);
|
||||
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reghi, left_reg.reghi));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reghi, left_reg.reghi));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, right_reg.reghi, left_reg.reghi, lfcmp64_L5));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, right_reg.reghi, left_reg.reghi, lfcmp64_L5);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, NR_TCR11, right_reg.reglo, left_reg.reglo));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, NR_TCR11, NR_R0, lfcmp64_L4));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SLTU, tmpreg2, right_reg.reglo, left_reg.reglo));
|
||||
//current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BNE, tmpreg2, NR_R0, lfcmp64_L4));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, tmpreg2, NR_R0, lfcmp64_L4);
|
||||
ai.setCondition(C_NE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmpreg1, 1));
|
||||
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
||||
cmp64_leu := NR_TCR10;
|
||||
cmp64_leu := tmpreg1;
|
||||
end;
|
||||
|
||||
function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister;
|
||||
@ -432,7 +503,7 @@ begin
|
||||
location_force_fpureg(current_asmdata.CurrAsmList, right.location, True);
|
||||
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := NR_TCR0;
|
||||
location.Register := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
|
||||
case NodeType of
|
||||
equaln:
|
||||
@ -442,11 +513,11 @@ begin
|
||||
else
|
||||
op := A_C_EQ_S;
|
||||
current_asmdata.getjumplabel(lfcmpfalse);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse)); //lfcmpfalse
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
|
||||
|
||||
end;
|
||||
@ -457,11 +528,11 @@ begin
|
||||
else
|
||||
op := A_C_EQ_S;
|
||||
current_asmdata.getjumplabel(lfcmpfalse);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1F, lfcmpfalse));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register , NR_R0, NR_R0));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
|
||||
end;
|
||||
ltn:
|
||||
@ -471,11 +542,11 @@ begin
|
||||
else
|
||||
op := A_C_LT_S;
|
||||
current_asmdata.getjumplabel(lfcmptrue);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
||||
end;
|
||||
lten:
|
||||
@ -485,11 +556,11 @@ begin
|
||||
else
|
||||
op := A_C_LE_S;
|
||||
current_asmdata.getjumplabel(lfcmptrue);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, left.location.Register, right.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
||||
end;
|
||||
gtn:
|
||||
@ -499,11 +570,11 @@ begin
|
||||
else
|
||||
op := A_C_LT_S;
|
||||
current_asmdata.getjumplabel(lfcmptrue);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
||||
end;
|
||||
gten:
|
||||
@ -513,11 +584,11 @@ begin
|
||||
else
|
||||
op := A_C_LE_S;
|
||||
current_asmdata.getjumplabel(lfcmptrue);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register{NR_TCR0}, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_const(A_ORI, location.Register, NR_R0, 1));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(op, right.location.Register, left.location.Register));
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_BC1T, lfcmptrue));
|
||||
current_asmdata.CurrAsmList.concat(TAiCpu.Op_none(A_NOP));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register {NR_TCR0}, NR_R0, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_OR, location.Register, NR_R0, NR_R0));
|
||||
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
||||
end;
|
||||
end; {case}
|
||||
@ -526,11 +597,12 @@ end;
|
||||
|
||||
procedure tmipsaddnode.second_cmpboolean;
|
||||
var
|
||||
tmp_right_reg: TRegister;
|
||||
tmp_right_reg, tmpreg: TRegister;
|
||||
begin
|
||||
pass_left_right;
|
||||
force_reg_left_right(True, True);
|
||||
tmp_right_reg := NR_NO;
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
if right.location.loc = LOC_CONSTANT then
|
||||
begin
|
||||
tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
@ -540,18 +612,19 @@ begin
|
||||
tmp_right_reg := right.location.Register;
|
||||
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
|
||||
location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
|
||||
end;
|
||||
|
||||
|
||||
procedure tmipsaddnode.second_cmpsmallset;
|
||||
var
|
||||
tmp_right_reg: TRegister;
|
||||
tmp_right_reg, tmpreg: TRegister;
|
||||
begin
|
||||
pass_left_right;
|
||||
force_reg_left_right(True, True);
|
||||
|
||||
tmp_right_reg := NR_NO;
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
|
||||
if right.location.loc = LOC_CONSTANT then
|
||||
begin
|
||||
@ -565,7 +638,7 @@ begin
|
||||
|
||||
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
|
||||
location.Register := GetRes_register(True, tmpreg, left.location.Register, tmp_right_reg);
|
||||
end;
|
||||
|
||||
|
||||
@ -582,20 +655,21 @@ begin
|
||||
not(is_signed(right.resultdef));
|
||||
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := GetRes64_register(unsigned, {NR_TCR0, }left.location.register64, right.location.register64); // NR_TCR0;
|
||||
location.Register := GetRes64_register(unsigned, left.location.register64, right.location.register64);
|
||||
end;
|
||||
|
||||
|
||||
procedure tmipsaddnode.second_cmpordinal;
|
||||
var
|
||||
unsigned: boolean;
|
||||
tmp_right_reg: TRegister;
|
||||
tmp_right_reg,tmpreg: TRegister;
|
||||
begin
|
||||
pass_left_right;
|
||||
force_reg_left_right(True, True);
|
||||
unsigned := not (is_signed(left.resultdef)) or not (is_signed(right.resultdef));
|
||||
|
||||
tmp_right_reg := NR_NO;
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
if right.location.loc = LOC_CONSTANT then
|
||||
begin
|
||||
tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
@ -604,7 +678,7 @@ begin
|
||||
else
|
||||
tmp_right_reg := right.location.Register;
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := getres_register(unsigned, NR_TCR0, left.location.Register, tmp_right_reg);
|
||||
location.Register := getres_register(unsigned, tmpreg, left.location.Register, tmp_right_reg);
|
||||
end;
|
||||
|
||||
begin
|
||||
|
@ -134,6 +134,7 @@ var
|
||||
href: treference;
|
||||
hregister: tregister;
|
||||
l1, l2: tasmlabel;
|
||||
ai : TaiCpu;
|
||||
|
||||
begin
|
||||
location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
|
||||
@ -149,7 +150,9 @@ begin
|
||||
|
||||
loadsigned;
|
||||
|
||||
current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg_sym(A_BGE, hregister, NR_R0, l2));
|
||||
ai := Taicpu.op_reg_reg_sym(A_BC, hregister, NR_R0, l2);
|
||||
ai.setCondition(C_GE);
|
||||
current_asmdata.CurrAsmList.concat(ai);
|
||||
|
||||
case tfloatdef(resultdef).floattype of
|
||||
{ converting dword to s64real first and cut off at the end avoids precision loss }
|
||||
@ -214,6 +217,8 @@ var
|
||||
hreg1, hreg2: tregister;
|
||||
opsize: tcgsize;
|
||||
hlabel, oldtruelabel, oldfalselabel: tasmlabel;
|
||||
newsize : tcgsize;
|
||||
href: treference;
|
||||
begin
|
||||
oldtruelabel := current_procinfo.CurrTrueLabel;
|
||||
oldfalselabel := current_procinfo.CurrFalseLabel;
|
||||
@ -223,17 +228,24 @@ begin
|
||||
if codegenerror then
|
||||
exit;
|
||||
|
||||
{ byte(boolean) or word(wordbool) or longint(longbool) must }
|
||||
{ be accepted for var parameters }
|
||||
if (nf_explicit in flags) and
|
||||
(left.resultdef.size = resultdef.size) and
|
||||
(left.location.loc in [LOC_REFERENCE, LOC_CREFERENCE, LOC_CREGISTER]) then
|
||||
begin
|
||||
location_copy(location, left.location);
|
||||
current_procinfo.CurrTrueLabel := oldtruelabel;
|
||||
current_procinfo.CurrFalseLabel := oldfalselabel;
|
||||
exit;
|
||||
end;
|
||||
{ Explicit typecasts from any ordinal type to a boolean type }
|
||||
{ must not change the ordinal value }
|
||||
if (nf_explicit in flags) and
|
||||
not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
|
||||
begin
|
||||
location_copy(location,left.location);
|
||||
newsize:=def_cgsize(resultdef);
|
||||
{ change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
|
||||
if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
|
||||
((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList,location,left.resultdef,resultdef,true)
|
||||
else
|
||||
location.size:=newsize;
|
||||
current_procinfo.CurrTrueLabel:=oldTrueLabel;
|
||||
current_procinfo.CurrFalseLabel:=oldFalseLabel;
|
||||
exit;
|
||||
end;
|
||||
|
||||
location_reset(location, LOC_REGISTER, def_cgsize(resultdef));
|
||||
opsize := def_cgsize(left.resultdef);
|
||||
case left.location.loc of
|
||||
@ -242,21 +254,35 @@ begin
|
||||
if left.location.loc in [LOC_CREFERENCE, LOC_REFERENCE] then
|
||||
begin
|
||||
hreg2 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2);
|
||||
{$ifndef cpu64bitalu}
|
||||
if left.location.size in [OS_64,OS_S64] then
|
||||
begin
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,left.location.reference,hreg2);
|
||||
hreg1:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
href:=left.location.reference;
|
||||
inc(href.offset,4);
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_INT,OS_INT,href,hreg1);
|
||||
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,hreg1,hreg2,hreg2);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList, opsize, opsize, left.location.reference, hreg2);
|
||||
end
|
||||
else
|
||||
hreg2 := left.location.Register;
|
||||
{$ifndef cpu64bit}
|
||||
if left.location.size in [OS_64, OS_S64] then
|
||||
begin
|
||||
hreg1 := cg.getintregister(current_asmdata.CurrAsmList, OS_32);
|
||||
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList, OP_OR, OS_32, hreg2, tregister(succ(longint(hreg2))), hreg1);
|
||||
hreg2 := hreg1;
|
||||
opsize := OS_32;
|
||||
end;
|
||||
{$endif cpu64bit}
|
||||
hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0));
|
||||
begin
|
||||
hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
|
||||
{$ifndef cpu64bitalu}
|
||||
if left.location.size in [OS_64,OS_S64] then
|
||||
begin
|
||||
hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
|
||||
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,left.location.register64.reglo,hreg2);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,hreg2);
|
||||
end;
|
||||
hreg1 := cg.getintregister(current_asmdata.CurrAsmList, opsize);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SNE, hreg1, hreg2, NR_R0));
|
||||
end;
|
||||
LOC_JUMP:
|
||||
begin
|
||||
@ -272,10 +298,26 @@ begin
|
||||
else
|
||||
internalerror(10062);
|
||||
end;
|
||||
location.Register := hreg1;
|
||||
{$ifndef cpu64bitalu}
|
||||
if (location.size in [OS_64,OS_S64]) then
|
||||
begin
|
||||
location.register64.reglo:=hreg1;
|
||||
location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
|
||||
if (is_cbool(resultdef)) then
|
||||
{ reglo is either 0 or -1 -> reghi has to become the same }
|
||||
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,location.register64.reglo,location.register64.reghi)
|
||||
else
|
||||
{ unsigned }
|
||||
cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,0,location.register64.reghi);
|
||||
end
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
location.Register := hreg1;
|
||||
|
||||
{zfx
|
||||
if location.size in [OS_64, OS_S64] then
|
||||
internalerror(200408241);
|
||||
}
|
||||
|
||||
current_procinfo.CurrTrueLabel := oldtruelabel;
|
||||
current_procinfo.CurrFalseLabel := oldfalselabel;
|
||||
|
@ -257,6 +257,7 @@ end;
|
||||
procedure tMIPSELnotnode.second_boolean;
|
||||
var
|
||||
hl: tasmlabel;
|
||||
tmpreg : TRegister;
|
||||
begin
|
||||
{ if the location is LOC_JUMP, we do the secondpass after the
|
||||
labels are allocated
|
||||
@ -283,10 +284,11 @@ begin
|
||||
end;
|
||||
LOC_REGISTER, LOC_CREGISTER, LOC_REFERENCE, LOC_CREFERENCE:
|
||||
begin
|
||||
tmpreg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
||||
hlcg.location_force_reg(current_asmdata.CurrAsmList, left.location, left.resultdef, left.resultdef, True);
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, NR_TCR0, left.location.Register, NR_R0));
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SEQ, tmpreg, left.location.Register, NR_R0));
|
||||
location_reset(location, LOC_REGISTER, OS_INT);
|
||||
location.Register := NR_TCR0;
|
||||
location.Register := tmpreg;
|
||||
end;
|
||||
else
|
||||
internalerror(2003042401);
|
||||
|
@ -1,5 +1,4 @@
|
||||
A_NONE,
|
||||
A_P_STK2,
|
||||
A_P_LW,
|
||||
A_P_SET_NOMIPS16,
|
||||
A_P_SET_NOREORDER,
|
||||
@ -15,7 +14,8 @@ A_NOP,
|
||||
A_NOT,
|
||||
A_NEG,
|
||||
A_NEGU,
|
||||
A_B,
|
||||
A_BA,
|
||||
A_BC,
|
||||
A_LI,
|
||||
A_DLI,
|
||||
A_LA,
|
||||
@ -108,22 +108,6 @@ A_J,
|
||||
A_JAL,
|
||||
A_JR,
|
||||
A_JALR,
|
||||
A_BEQ,
|
||||
A_BNE,
|
||||
A_BLEZ,
|
||||
A_BGTZ,
|
||||
A_BLTZ,
|
||||
A_BGEZ,
|
||||
A_BLTZAL,
|
||||
A_BGEZAL,
|
||||
A_BEQL,
|
||||
A_BNEL,
|
||||
A_BLEZL,
|
||||
A_BGTZL,
|
||||
A_BLTZL,
|
||||
A_BGEZL,
|
||||
A_BLTZALL,
|
||||
A_BGEZALL,
|
||||
A_SLL,
|
||||
A_SRL,
|
||||
A_SRA,
|
||||
@ -193,32 +177,12 @@ A_FLOOR_L_S,
|
||||
A_FLOOR_L_D,
|
||||
A_BC1T,
|
||||
A_BC1F,
|
||||
A_BC1TL,
|
||||
A_BC1FL,
|
||||
A_C_EQ_D,
|
||||
A_C_EQ_S,
|
||||
A_C_LE_D,
|
||||
A_C_LE_S,
|
||||
A_C_LT_D,
|
||||
A_C_LT_S,
|
||||
A_BEQI,
|
||||
A_BNEI,
|
||||
A_BLTI,
|
||||
A_BLEI,
|
||||
A_BGTI,
|
||||
A_BGEI,
|
||||
A_BLTUI,
|
||||
A_BLEUI,
|
||||
A_BGTUI,
|
||||
A_BGEUI,
|
||||
A_BLT,
|
||||
A_BLE,
|
||||
A_BGT,
|
||||
A_BGE,
|
||||
A_BLTU,
|
||||
A_BLEU,
|
||||
A_BGTU,
|
||||
A_BGEU,
|
||||
A_SEQ,
|
||||
A_SGE,
|
||||
A_SGEU,
|
||||
|
@ -639,7 +639,7 @@ Interface
|
||||
begin
|
||||
{ we can search here without an extra table which is sorted by string length
|
||||
because we take the whole remaining string without the leading B }
|
||||
actopcode := A_B;
|
||||
actopcode := A_BC;
|
||||
for cond:=low(TAsmCond) to high(TAsmCond) do
|
||||
if (Upper(copy(s,2,length(s)-1))=Upper(Cond2Str[cond])) then
|
||||
begin
|
||||
|
@ -1,5 +1,4 @@
|
||||
'none',
|
||||
'p_stk2',
|
||||
'p_lw',
|
||||
'p_set_nomips16',
|
||||
'p_set_noreorder',
|
||||
@ -15,6 +14,7 @@
|
||||
'not',
|
||||
'neg',
|
||||
'negu',
|
||||
'b ',
|
||||
'b',
|
||||
'li',
|
||||
'dli',
|
||||
@ -108,22 +108,6 @@
|
||||
'jal',
|
||||
'jr',
|
||||
'jalr',
|
||||
'beq',
|
||||
'bne',
|
||||
'blez',
|
||||
'bgtz',
|
||||
'bltz',
|
||||
'bgez',
|
||||
'bltzal',
|
||||
'bgezal',
|
||||
'beql',
|
||||
'bnel',
|
||||
'blezl',
|
||||
'bgtzl',
|
||||
'bltzl',
|
||||
'bgezl',
|
||||
'bltzall',
|
||||
'bgezall',
|
||||
'sll',
|
||||
'srl',
|
||||
'sra',
|
||||
@ -193,32 +177,12 @@
|
||||
'floor.l.d',
|
||||
'bc1t',
|
||||
'bc1f',
|
||||
'bc1tl',
|
||||
'bc1fl',
|
||||
'c.eq.d',
|
||||
'c.eq.s',
|
||||
'c.le.d',
|
||||
'c.le.s',
|
||||
'c.lt.d',
|
||||
'c.lt.s',
|
||||
'beqi',
|
||||
'bnei',
|
||||
'blti',
|
||||
'blei',
|
||||
'bgti',
|
||||
'bgei',
|
||||
'bltui',
|
||||
'bleui',
|
||||
'bgtui',
|
||||
'bgeui',
|
||||
'blt',
|
||||
'ble',
|
||||
'bgt',
|
||||
'bge',
|
||||
'bltu',
|
||||
'bleu',
|
||||
'bgtu',
|
||||
'bgeu',
|
||||
'seq',
|
||||
'sge',
|
||||
'sgeu',
|
||||
|
Loading…
Reference in New Issue
Block a user