| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | {    Copyright (c) 2000-2002 by Florian Klaempfl and Jonas Maebe    Code generation for add nodes on the Risc-V32    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 nrv32add;{$i fpcdefs.inc}  interface    uses      node, ncgadd, aasmbase, nrvadd, cpubase,      cgbase;    type      trv32addnode = class(trvaddnode)      private        procedure cmp64_le(left_reg, right_reg: TRegister64; unsigned: boolean);        procedure cmp64_lt(left_reg, right_reg: TRegister64; unsigned: boolean);      protected        function use_generic_mul32to64: boolean; override;        procedure second_cmp64bit; override;      end;  implementation    uses      systems,      cutils,verbose,      paramgr,procinfo,      aasmtai,aasmdata,aasmcpu,defutil,      cgcpu,cgutils,nadd,      cpupara,      ncon,nset,      hlcgobj, ncgutil,cgobj;    const      cmpops: array[boolean] of TOpCmp = (OC_LT,OC_B);    procedure trv32addnode.cmp64_lt(left_reg, right_reg: TRegister64;unsigned: boolean);      begin        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],right_reg.reghi,left_reg.reghi,location.truelabel);        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,right_reg.reglo,left_reg.reglo,location.truelabel);        cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);      end;    procedure trv32addnode.cmp64_le(left_reg, right_reg: TRegister64;unsigned: boolean);      begin        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cmpops[unsigned],left_reg.reghi,right_reg.reghi,location.falselabel);        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);        cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_B,left_reg.reglo,right_reg.reglo,location.falselabel);        cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);      end;    function trv32addnode.use_generic_mul32to64: boolean;      begin        result:=true;      end;    procedure trv32addnode.second_cmp64bit;      var        truelabel,        falselabel: tasmlabel;        unsigned: boolean;        left_reg,right_reg: TRegister64;      begin        current_asmdata.getjumplabel(truelabel);        current_asmdata.getjumplabel(falselabel);        location_reset_jump(location,truelabel,falselabel);        pass_left_right;        force_reg_left_right(true,true);        unsigned:=not(is_signed(left.resultdef)) or                  not(is_signed(right.resultdef));        left_reg:=left.location.register64;        if (right.location.loc=LOC_CONSTANT) then          begin            if lo(right.location.value64)=0 then              right_reg.reglo:=NR_X0            else              begin                right_reg.reglo:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,lo(right.location.value64),right_reg.reglo);              end;            if hi(right.location.value64)=0 then              right_reg.reghi:=NR_X0            else              begin                right_reg.reghi:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);                cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,hi(right.location.value64),right_reg.reghi);              end;          end        else          right_reg:=right.location.register64;        case NodeType of          equaln:            begin              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.falselabel);              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.falselabel);              cg.a_jmp_always(current_asmdata.CurrAsmList,location.truelabel);            end;          unequaln:            begin              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reghi,right_reg.reghi,location.truelabel);              cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left_reg.reglo,right_reg.reglo,location.truelabel);              cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);            end;        else          if nf_swapped in flags then            case NodeType of              ltn:                cmp64_lt(right_reg, left_reg,unsigned);              lten:                cmp64_le(right_reg, left_reg,unsigned);              gtn:                cmp64_lt(left_reg, right_reg,unsigned);              gten:                cmp64_le(left_reg, right_reg,unsigned);              else                internalerror(2019051034);            end          else            case NodeType of              ltn:                cmp64_lt(left_reg, right_reg,unsigned);              lten:                cmp64_le(left_reg, right_reg,unsigned);              gtn:                cmp64_lt(right_reg, left_reg,unsigned);              gten:                cmp64_le(right_reg, left_reg,unsigned);              else                internalerror(2019051033);            end;        end;      end;begin   caddnode:=trv32addnode;end.
 |