123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- {
- Copyright (C) 2022 Loongson Technology Corporation Limited.
- Contains the assembler object for the LoongArch64
- 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 aasmcpu;
- {$i fpcdefs.inc}
- interface
- uses
- globtype,verbose,
- aasmbase,aasmtai,aasmdata,aasmsym,
- cpubase,cgbase,cgutils;
- const
- { "move reg,reg" source operand number }
- O_MOV_SOURCE = 1;
- { "move reg,reg" source operand number }
- O_MOV_DEST = 0;
- type
- { TODO: Branch condition? TRefernece and Symbol? }
- { taicpu }
- taicpu = class(tai_cpu_abstract_sym)
- { NOP,TLBSRCH,TLBRD,TLBWR,TLBFILL,TLBCLR,TLBFLUSH,ERTN, }
- constructor op_none(op : tasmop);
- { DBAR,IBAR,SYSCALL,BREAK,DBCL,IDLE, }
- constructor op_const(op : tasmop;_op1 : aint);
- { B,BL,JR, }
- constructor op_ref(op : tasmop; const _op1 : treference);
- { EXT,CLO,CLZ,CTO,CTZ,REVB,REVH,BITREV,ASRTLE,ASRTGT,RDTIMEL,RDTIMEH,
- RDTIME,CPUCFG,FABS,FNEG,FSQRT,FRECIP,FRSQRT,FLOGB,FCLASS,FCVT,FFINT,
- FTINT,FTINTRM,FTINTRP,FTINTRZ,FTINTRNE,FRINT,FMOV,MOVGR2FR,MOVGR2FRH,
- MOVFR2GR,MOVFRH2GR,MOVGR2FCSR,MOVFCSR2GR,MOVFR2CF,MOVCF2FR,MOVGR2CF,
- MOVCF2GR,IOCSRRD,IOCSRWR,MOVE,}
- constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
- { BEQZ,BNEZ,BCEQZ,BCNEZ,LA,BLTZ,BGTZ,BGEZ,BLEZ,LD,ST,LDX,STX,LDPTR,
- STPTR,FLD,FST,FLDX,FSTX, }
- constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
- { LU12I,LU32I,PCADDI,PCADDU12I,PCADDU18I,PCALAU12I,CSRRD,CSRWR,LDPTE,LI, }
- constructor op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
- { BSTRINS,BSTRPICK, }
- constructor op_reg_reg_const_const(op: tasmop; _op1, _op2: tregister; _op3, _op4: aint);
- { ADD,SUB,SLT,AND,OR,NOR,XOR,ANDN,ORN,MUL,MULH,MULW,DIV,MOD,SLL,SRL,SRA,
- RTOR,MASKEQZ,MASKNEZ,LDGT,LDLE,STGT,STLE,AMSWAP,AMSWAP_DB,AMADD,AMADD_DB,
- AMAND,AMAND_DB,AMOR,AMOR_DB,AMXOR,AMXOR_DB,AMMAX,AMMAX_DB,AMMIN,AMMIN_DB,
- CRC,CRCC,FADD,FSUB,FMUL,FDIV,FMAX,FMIN,FMAXA,FMINA,FCALEB,FCOPYSIGN,FCMP,
- FLDGT,FLDLE,FSTGT,FSTLE,}
- constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
- { ADDI,ADDU16I,LU52I,SLTI,ANDI,ORI,XORI,SLLI,SRLI,SRAI,ROTRI,JIRL,LL,SC,
- CSRXCHG,LDDIR,}
- constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
- { BEQ,BNE,BLT,BGE,BLTU,BGEU,BGT,BLE,BGTU,BLEU, }
- constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
- { PRELD,CACOP, }
- constructor op_const_reg_const(op : tasmop;_op1 : aint;_op2 : tregister;_op3 : aint);
- { PRELDX,INVTLB }
- constructor op_const_reg_reg(op : tasmop; _op1 : aint; _op2,_op3 : tregister);
- { FMADD,FMSUB,FNMADD,FNMSUB,FSEL,}
- constructor op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
- { ALSL,BYTEPICK, }
- constructor op_reg_reg_reg_const(op : tasmop; _op1, _op2, _op3 : tregister; _op4 : aint);
- function is_same_reg_move(regtype: Tregistertype):boolean; override;
- { register spilling code }
- function spilling_get_operation_type(opnr: longint): topertype;override;
- function spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype;override;
- end;
- tai_align = class(tai_align_abstract)
- { nothing to add }
- end;
- procedure InitAsm;
- procedure DoneAsm;
- function spilling_create_load(const ref:treference;r:tregister):Taicpu;
- function spilling_create_store(r:tregister; const ref:treference):Taicpu;
- implementation
- uses cutils, cclasses;
- {*****************************************************************************
- taicpu Constructors
- *****************************************************************************}
- constructor taicpu.op_none(op : tasmop);
- begin
- inherited create(op);
- end;
- constructor taicpu.op_const(op : tasmop;_op1 : aint);
- begin
- inherited create(op);
- ops:=1;
- loadconst(0,_op1);
- end;
- constructor taicpu.op_ref(op : tasmop;const _op1 : treference);
- begin
- inherited create(op);
- ops:=1;
- loadref(0,_op1);
- end;
- constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
- begin
- inherited create(op);
- ops:=2;
- loadreg(0,_op1);
- loadreg(1,_op2);
- end;
- constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
- begin
- inherited create(op);
- ops:=2;
- loadreg(0,_op1);
- loadref(1,_op2);
- end;
- constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: aint);
- begin
- inherited create(op);
- ops:=2;
- loadreg(0,_op1);
- loadconst(1,_op2);
- end;
- constructor taicpu.op_reg_reg_const_const(op: tasmop; _op1, _op2: tregister; _op3, _op4: aint);
- begin
- inherited create(op);
- ops := 4;
- loadreg(0, _op1);
- loadreg(1, _op2);
- loadconst(2, _op3);
- loadconst(3, _op4);
- end;
- constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
- begin
- inherited create(op);
- ops:=3;
- loadreg(0,_op1);
- loadreg(1,_op2);
- loadreg(2,_op3);
- end;
- constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint);
- begin
- inherited create(op);
- ops:=3;
- loadreg(0,_op1);
- loadreg(1,_op2);
- loadconst(2,_op3);
- end;
- constructor taicpu.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference);
- begin
- inherited create(op);
- ops:=3;
- loadreg(0,_op1);
- loadreg(1,_op2);
- loadref(2,_op3);
- end;
- constructor taicpu.op_const_reg_reg(op : tasmop;_op1 : aint;_op2, _op3 : tregister);
- begin
- inherited create(op);
- ops:=3;
- loadconst(0,_op1);
- loadreg(1,_op2);
- loadreg(2,_op3);
- end;
- constructor taicpu.op_const_reg_const(op : tasmop;_op1 : aint;_op2 : tregister;_op3 : aint);
- begin
- inherited create(op);
- ops:=3;
- loadconst(0,_op1);
- loadreg(1,_op2);
- loadconst(2,_op3);
- end;
- constructor taicpu.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
- begin
- inherited create(op);
- ops:=4;
- loadreg(0,_op1);
- loadreg(1,_op2);
- loadreg(2,_op3);
- loadreg(3,_op4);
- end;
- constructor taicpu.op_reg_reg_reg_const(op : tasmop; _op1, _op2, _op3 : tregister; _op4 : aint);
- begin
- inherited create(op);
- ops := 4;
- loadreg(0, _op1);
- loadreg(1, _op2);
- loadreg(2, _op3);
- loadconst(3, cardinal(_op4));
- end;
- { ****************************** newra stuff *************************** }
- function taicpu.is_same_reg_move(regtype: Tregistertype):boolean;
- begin
- case regtype of
- R_INTREGISTER:
- result:=
- (opcode=A_MOVE) and (oper[0]^.reg=oper[1]^.reg);
- R_FPUREGISTER:
- result:=
- ((opcode=A_FMOV_S) or (opcode=A_FMOV_D)) and
- (oper[0]^.reg=oper[1]^.reg);
- else
- result:=false;
- end;
- end;
- { Mant of case is set opnr0 and read from opnr(others). }
- function normal_oper_type(opnr: longint): topertype;
- begin
- if opnr=0 then
- result:=operand_write
- else
- result:=operand_read;
- end;
- function taicpu.spilling_get_operation_type(opnr: longint): topertype;
- begin
- case opcode of
- A_ST_B,A_ST_D,A_ST_W,A_ST_H,A_STX_B,A_STX_D,A_STX_W,A_STX_H,
- A_STPTR_W,A_STPTR_D,A_STGT_B,A_STGT_D,A_STGT_W,A_STGT_H,
- A_STLE_B,A_STLE_D,A_STLE_W,A_STLE_H,A_FST_S,A_FST_D,A_FSTX_S,
- A_FSTX_D,A_FSTGT_S,A_FSTGT_D,A_FSTLE_S,A_FSTLE_D,A_CSRWR,
- A_IOCSRWR_B,A_IOCSRWR_D,A_IOCSRWR_W,A_IOCSRWR_H:
- result:=operand_read;
- A_RDTIME_D,A_RDTIMEL_W,A_RDTIMEH_W:
- result:=operand_write;
- A_PRELD,A_PRELDX,A_DBAR,A_IBAR,A_SYSCALL,A_BREAK,A_ASRTLE_D,
- A_ASRTGT_D,A_CACOP,A_INVTLB,A_DBCL,A_IDLE,A_BEQ,A_BNE,A_BLT,
- A_BLTU,A_BGE,A_BGEU,A_BEQZ,A_BNEZ,A_B,A_BL,A_BCEQZ,A_BCNEZ,
- A_BLTZ,A_BGTZ,A_BGEZ,A_BLEZ,A_BGT,A_BLE,A_BGTU,A_BLEU,A_JR,
- A_NOP,A_BXX:
- result:=operand_read;
- A_AMSWAP_W,A_AMSWAP_D,A_AMSWAP_DB_W,A_AMSWAP_DB_D,A_AMADD_W,
- A_AMADD_D,A_AMADD_DB_W,A_AMADD_DB_D,A_AMAND_W,A_AMAND_D,
- A_AMAND_DB_W,A_AMAND_DB_D,A_AMOR_W,A_AMOR_D,A_AMOR_DB_W,
- A_AMOR_DB_D,A_AMXOR_W,A_AMXOR_D,A_AMXOR_DB_W,A_AMXOR_DB_D,
- A_AMMAX_W,A_AMMAX_DU,A_AMMAX_D,A_AMMAX_WU,A_AMMAX_DB_W,
- A_AMMAX_DB_DU,A_AMMAX_DB_D,A_AMMAX_DB_WU,A_AMMIN_W,A_AMMIN_DU,
- A_AMMIN_D,A_AMMIN_WU,A_AMMIN_DB_W,A_AMMIN_DB_DU,A_AMMIN_DB_D,
- A_AMMIN_DB_WU,A_SC_W,A_SC_D:
- result:=operand_readwrite;
- else
- result:=normal_oper_type(opnr);
- end;
- end;
- function taicpu.spilling_get_operation_type_ref(opnr: longint; reg: tregister): topertype;
- begin
- result := operand_read;
- end;
- function spilling_create_load(const ref:treference;r:tregister):Taicpu;
- var
- href : treference;
- begin
- href:=ref;
- href.refaddr:=addr_reg_12i;
- case getregtype(r) of
- R_INTREGISTER: result:=taicpu.op_reg_ref(A_LD_D,r,href);
- R_FPUREGISTER: result:=taicpu.op_reg_ref(A_FLD_D,r,href);
- else
- internalerror(2022111904);
- end;
- end;
- function spilling_create_store(r:tregister; const ref:treference):Taicpu;
- var
- href : treference;
- begin
- href:=ref;
- href.refaddr:=addr_reg_12i;
- case getregtype(r) of
- R_INTREGISTER: result:=taicpu.op_reg_ref(A_ST_D,r,href);
- R_FPUREGISTER: result:=taicpu.op_reg_ref(A_FST_D,r,href);
- else
- internalerror(2022111905);
- end;
- end;
- procedure InitAsm;
- begin
- end;
- procedure DoneAsm;
- begin
- end;
- begin
- cai_align:=tai_align;
- cai_cpu:=taicpu;
- end.
|