mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 14:39:36 +01: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.
 |