fpc/compiler/mips/ncpuadd.pas
florian 28ac4a8dda * several mips/mipsel related stuff fixed
* regenerated linux makefile to support mipsel

git-svn-id: trunk@14278 -
2009-11-27 15:10:56 +00:00

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.