mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-01 20:53:41 +02:00
599 lines
21 KiB
ObjectPascal
599 lines
21 KiB
ObjectPascal
{
|
|
Copyright (c) 2000-2009 by Florian Klaempfl and David Zhang
|
|
|
|
Code generation for add nodes on the FVM32
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
unit ncpuadd;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
node, ncgadd, cpubase, aasmbase, cgbase;
|
|
|
|
type
|
|
tmipsaddnode = class(tcgaddnode)
|
|
private
|
|
function cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
|
|
function cmp64_le(left_reg, right_reg: TRegister64): TRegister;
|
|
function cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
|
|
function cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
|
|
function cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
|
|
function cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
|
|
|
|
function GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
|
|
function GetRes64_register(unsigned: boolean; {this_reg,} left_reg, right_reg: TRegister64): TRegister;
|
|
protected
|
|
procedure second_addfloat; override;
|
|
procedure second_cmpfloat; override;
|
|
procedure second_cmpboolean; override;
|
|
procedure second_cmpsmallset; override;
|
|
procedure second_cmp64bit; override;
|
|
procedure second_cmpordinal; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
systems,
|
|
cutils, verbose,
|
|
paramgr,
|
|
aasmtai, aasmcpu, aasmdata,
|
|
defutil,
|
|
{cgbase,} cgcpu, cgutils,
|
|
cpupara,
|
|
ncon, nset, nadd,
|
|
ncgutil, cgobj;
|
|
|
|
{*****************************************************************************
|
|
tmipsaddnode
|
|
*****************************************************************************}
|
|
function tmipsaddnode.GetRes_register(unsigned: boolean; this_reg, left_reg, right_reg: TRegister): TRegister;
|
|
var
|
|
tmp_asm_op: tasmop;
|
|
begin
|
|
case NodeType of
|
|
equaln:
|
|
tmp_asm_op := A_SEQ;
|
|
unequaln:
|
|
tmp_asm_op := A_SNE;
|
|
else
|
|
if not (unsigned) then
|
|
begin
|
|
if nf_swapped in flags then
|
|
case NodeType of
|
|
ltn:
|
|
tmp_asm_op := A_SGT;
|
|
lten:
|
|
tmp_asm_op := A_SGE;
|
|
gtn:
|
|
tmp_asm_op := A_SLT;
|
|
gten:
|
|
tmp_asm_op := A_SLE;
|
|
end
|
|
else
|
|
case NodeType of
|
|
ltn:
|
|
tmp_asm_op := A_SLT;
|
|
lten:
|
|
tmp_asm_op := A_SLE;
|
|
gtn:
|
|
tmp_asm_op := A_SGT;
|
|
gten:
|
|
tmp_asm_op := A_SGE;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if nf_swapped in Flags then
|
|
case NodeType of
|
|
ltn:
|
|
tmp_asm_op := A_SGTU;
|
|
lten:
|
|
tmp_asm_op := A_SGEU;
|
|
gtn:
|
|
tmp_asm_op := A_SLTU;
|
|
gten:
|
|
tmp_asm_op := A_SLEU;
|
|
end
|
|
else
|
|
case NodeType of
|
|
ltn:
|
|
tmp_asm_op := A_SLTU;
|
|
lten:
|
|
tmp_asm_op := A_SLEU;
|
|
gtn:
|
|
tmp_asm_op := A_SGTU;
|
|
gten:
|
|
tmp_asm_op := A_SGEU;
|
|
end;
|
|
end;
|
|
end;
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(tmp_asm_op, this_reg, left_reg, right_reg));
|
|
GetRes_register := this_reg;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_eq(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4: tasmlabel;
|
|
begin
|
|
|
|
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_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_none(A_NOP));
|
|
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_eq := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_ne(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4: tasmlabel;
|
|
begin
|
|
|
|
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_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_none(A_NOP));
|
|
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 0));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_ne := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_lt(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 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_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_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_none(A_NOP));
|
|
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, 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));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_lt := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_le(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 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_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_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_none(A_NOP));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_le := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_ltu(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 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_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_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_none(A_NOP));
|
|
current_asmdata.CurrAsmList.concat(Taicpu.op_sym(A_B, 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));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_ltu := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.cmp64_leu(left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
lfcmp64_L4, lfcmp64_L5: tasmlabel;
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 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_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_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_none(A_NOP));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L5);
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, NR_TCR10, 1));
|
|
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmp64_L4);
|
|
cmp64_leu := NR_TCR10;
|
|
end;
|
|
|
|
function tmipsaddnode.GetRes64_register(unsigned: boolean; //this_reg: TRegister;
|
|
left_reg, right_reg: TRegister64): TRegister;
|
|
var
|
|
tmpreg: TRegister;
|
|
lfcmp64_L4, lfcmp_L5: tasmlabel;
|
|
begin
|
|
case NodeType of
|
|
equaln:
|
|
begin
|
|
GetRes64_register := cmp64_eq(left_reg, right_reg);
|
|
end;
|
|
unequaln:
|
|
GetRes64_register := cmp64_ne(left_reg, right_reg);
|
|
else
|
|
if not (unsigned) then
|
|
begin
|
|
if nf_swapped in flags then
|
|
case NodeType of
|
|
ltn:
|
|
GetRes64_register := cmp64_lt(right_reg, left_reg);
|
|
lten:
|
|
GetRes64_register := cmp64_le(right_reg, left_reg);
|
|
gtn:
|
|
GetRes64_register := cmp64_lt(left_reg, right_reg);
|
|
gten:
|
|
GetRes64_register := cmp64_le(left_reg, right_reg);
|
|
end
|
|
else
|
|
case NodeType of
|
|
ltn:
|
|
GetRes64_register := cmp64_lt(left_reg, right_reg);
|
|
lten:
|
|
GetRes64_register := cmp64_le(left_reg, right_reg);
|
|
gtn:
|
|
GetRes64_register := cmp64_lt(right_reg, left_reg);
|
|
gten:
|
|
GetRes64_register := cmp64_le(right_reg, left_reg);
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
if nf_swapped in Flags then
|
|
case NodeType of
|
|
ltn:
|
|
GetRes64_register := cmp64_ltu(right_reg, left_reg);
|
|
lten:
|
|
GetRes64_register := cmp64_leu(right_reg, left_reg);
|
|
gtn:
|
|
GetRes64_register := cmp64_ltu(left_reg, right_reg);
|
|
gten:
|
|
GetRes64_register := cmp64_leu(left_reg, right_reg);
|
|
end
|
|
else
|
|
case NodeType of
|
|
ltn:
|
|
GetRes64_register := cmp64_ltu(left_reg, right_reg);
|
|
lten:
|
|
GetRes64_register := cmp64_leu(left_reg, right_reg);
|
|
gtn:
|
|
GetRes64_register := cmp64_ltu(right_reg, left_reg);
|
|
gten:
|
|
GetRes64_register := cmp64_leu(right_reg, left_reg);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure tmipsaddnode.second_addfloat;
|
|
var
|
|
op: TAsmOp;
|
|
begin
|
|
pass_left_right;
|
|
if (nf_swapped in flags) then
|
|
swapleftright;
|
|
|
|
{ force fpureg as location, left right doesn't matter
|
|
as both will be in a fpureg }
|
|
location_force_fpureg(current_asmdata.CurrAsmList, left.location, True);
|
|
location_force_fpureg(current_asmdata.CurrAsmList, right.location, (left.location.loc <> LOC_CFPUREGISTER));
|
|
|
|
location_reset(location, LOC_FPUREGISTER, def_cgsize(resultdef));
|
|
if left.location.loc <> LOC_CFPUREGISTER then
|
|
location.Register := left.location.Register
|
|
else
|
|
location.Register := right.location.Register;
|
|
|
|
case nodetype of
|
|
addn:
|
|
begin
|
|
if location.size = OS_F64 then
|
|
op := A_ADD_D
|
|
else
|
|
op := A_ADD_S;
|
|
end;
|
|
muln:
|
|
begin
|
|
if location.size = OS_F64 then
|
|
op := A_MUL_D
|
|
else
|
|
op := A_MUL_S;
|
|
end;
|
|
subn:
|
|
begin
|
|
if location.size = OS_F64 then
|
|
op := A_SUB_D
|
|
else
|
|
op := A_SUB_S;
|
|
end;
|
|
slashn:
|
|
begin
|
|
if location.size = OS_F64 then
|
|
op := A_DIV_D
|
|
else
|
|
op := A_DIV_S;
|
|
end;
|
|
else
|
|
internalerror(200306014);
|
|
end;
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(op,
|
|
location.Register, left.location.Register, right.location.Register));
|
|
|
|
end;
|
|
|
|
|
|
procedure tmipsaddnode.second_cmpfloat;
|
|
var
|
|
op: tasmop;
|
|
lfcmptrue, lfcmpfalse: tasmlabel;
|
|
begin
|
|
pass_left_right;
|
|
if nf_swapped in flags then
|
|
swapleftright;
|
|
|
|
{ force fpureg as location, left right doesn't matter
|
|
as both will be in a fpureg }
|
|
location_force_fpureg(current_asmdata.CurrAsmList, left.location, True);
|
|
location_force_fpureg(current_asmdata.CurrAsmList, right.location, True);
|
|
|
|
location_reset(location, LOC_REGISTER, OS_INT);
|
|
location.Register := NR_TCR0;
|
|
|
|
case NodeType of
|
|
equaln:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_EQ_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
|
|
|
|
end;
|
|
unequaln:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_EQ_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmpfalse);
|
|
end;
|
|
ltn:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_LT_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
|
end;
|
|
lten:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_LE_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
|
end;
|
|
gtn:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_LT_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
|
end;
|
|
gten:
|
|
begin
|
|
if left.location.size = OS_F64 then
|
|
op := A_C_LE_D
|
|
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(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));
|
|
cg.a_label(current_asmdata.CurrAsmList, lfcmptrue);
|
|
end;
|
|
end; {case}
|
|
end;
|
|
|
|
|
|
procedure tmipsaddnode.second_cmpboolean;
|
|
var
|
|
tmp_right_reg: TRegister;
|
|
begin
|
|
pass_left_right;
|
|
force_reg_left_right(True, True);
|
|
tmp_right_reg := NR_NO;
|
|
if right.location.loc = LOC_CONSTANT then
|
|
begin
|
|
tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
|
|
end
|
|
else
|
|
begin
|
|
tmp_right_reg := right.location.Register;
|
|
end;
|
|
|
|
location_reset(location, LOC_REGISTER, OS_INT);
|
|
location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
|
|
|
|
end;
|
|
|
|
|
|
procedure tmipsaddnode.second_cmpsmallset;
|
|
var
|
|
tmp_right_reg: TRegister;
|
|
begin
|
|
pass_left_right;
|
|
force_reg_left_right(True, True);
|
|
|
|
tmp_right_reg := NR_NO;
|
|
|
|
if right.location.loc = LOC_CONSTANT then
|
|
begin
|
|
tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
|
|
end
|
|
else
|
|
begin
|
|
tmp_right_reg := right.location.Register;
|
|
end;
|
|
|
|
|
|
location_reset(location, LOC_REGISTER, OS_INT);
|
|
location.Register := GetRes_register(True, NR_TCR0, left.location.Register, tmp_right_reg);
|
|
end;
|
|
|
|
|
|
procedure tmipsaddnode.second_cmp64bit;
|
|
var
|
|
unsigned : boolean;
|
|
tmp_left_reg: TRegister;
|
|
|
|
begin
|
|
pass_left_right;
|
|
force_reg_left_right(false,false);
|
|
|
|
unsigned:=not(is_signed(left.resultdef)) or
|
|
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;
|
|
end;
|
|
|
|
|
|
procedure tmipsaddnode.second_cmpordinal;
|
|
var
|
|
unsigned: boolean;
|
|
tmp_right_reg: 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;
|
|
if right.location.loc = LOC_CONSTANT then
|
|
begin
|
|
tmp_right_reg := cg.GetIntRegister(current_asmdata.CurrAsmList, OS_INT);
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_reg_const(A_LI, tmp_right_reg, right.location.Value));
|
|
end
|
|
else
|
|
begin
|
|
tmp_right_reg := right.location.Register;
|
|
end;
|
|
location_reset(location, LOC_REGISTER, OS_INT);
|
|
location.Register := getres_register(unsigned, NR_TCR0, left.location.Register, tmp_right_reg);
|
|
end;
|
|
|
|
begin
|
|
caddnode := tmipsaddnode;
|
|
end.
|