mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 21:49:46 +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.
 | 
