123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- {
- Copyright (c) 1999-2009 by Mazen Neifer and David Zhang
- Contains the assembler object for the MIPSEL
- 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
- cclasses,
- globtype, globals, verbose,
- aasmbase, aasmsym, aasmtai,
- cgbase, cgutils, cpubase, cpuinfo;
- const
- { "mov reg,reg" source operand number }
- O_MOV_SOURCE = 0;
- { "mov reg,reg" source operand number }
- O_MOV_DEST = 1;
- type
- taicpu = class(tai_cpu_abstract_sym)
- delayslot_annulled: boolean; { conditinal opcode with ,a }
- constructor op_none(op: tasmop);
- constructor op_reg(op: tasmop; _op1: tregister);
- constructor op_const(op: tasmop; _op1: longint);
- constructor op_ref(op: tasmop; const _op1: treference);
- constructor op_reg_reg(op: tasmop; _op1, _op2: tregister);
- constructor op_reg_ref(op: tasmop; _op1: tregister; const _op2: treference);
- constructor op_reg_const(op: tasmop; _op1: tregister; _op2: longint);
- constructor op_reg_reg_reg(op: tasmop; _op1, _op2, _op3: tregister);
- constructor op_reg_reg_ref(op: tasmop; _op1, _op2: tregister; const _op3: treference);
- constructor op_reg_reg_const(op: tasmop; _op1, _op2: tregister; _op3: aint);
- { this is for Jmp instructions }
- constructor op_sym(op: tasmop; _op1: tasmsymbol);
- constructor op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
- constructor op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol);
- constructor op_sym_ofs(op: tasmop; _op1: tasmsymbol; _op1ofs: longint);
- { register allocation }
- function is_same_reg_move(regtype: Tregistertype): boolean; override;
- { register spilling code }
- function spilling_get_operation_type(opnr: longint): 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
- {*****************************************************************************
- taicpu Constructors
- *****************************************************************************}
- constructor taicpu.op_none(op: tasmop);
- begin
- inherited Create(op);
- end;
- constructor taicpu.op_reg(op: tasmop; _op1: tregister);
- begin
- inherited Create(op);
- ops := 1;
- loadreg(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_const(op: tasmop; _op1: longint);
- begin
- inherited Create(op);
- ops := 1;
- loadconst(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_const(op: tasmop; _op1: tregister; _op2: longint);
- begin
- inherited Create(op);
- ops := 2;
- loadreg(0, _op1);
- loadconst(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_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_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_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_sym(op: tasmop; _op1: tasmsymbol);
- begin
- inherited Create(op);
- is_jmp := op in [A_J, A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI,
- A_BLTUI, A_BLEUI, A_BGTUI, A_BGEUI,
- A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE,
- A_BLTU, A_BLEU, A_BGTU, A_BGEU
- ];
- ops := 1;
- loadsymbol(0, _op1, 0);
- end;
- constructor taicpu.op_reg_reg_sym(op: tasmop; _op1, _op2: tregister; _op3: tasmsymbol);
- begin
- inherited create(op);
- is_jmp := op in [A_J,
- A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
- A_BGTUI, A_BGEUI,
- A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU];
- ops := 3;
- loadreg(0, _op1);
- loadreg(1, _op2);
- loadsymbol(2, _op3, 0);
- end;
- constructor taicpu.op_reg_sym(op: tasmop; _op1: tregister; _op2: tasmsymbol);
- begin
- inherited create(op);
- is_jmp := op in [A_J,
- A_BEQI, A_BNEI, A_BLTI, A_BLEI, A_BGTI, A_BGEI, A_BLTUI, A_BLEUI,
- A_BGTUI, A_BGEUI,
- A_BEQ, A_BNE, A_BLT, A_BLE, A_BGT, A_BGE, A_BLTU, A_BLEU, A_BGTU, A_BGEU, A_BGTZ];
- ops := 2;
- loadreg(0, _op1);
- loadsymbol(1, _op2, 0);
- end;
- constructor taicpu.op_sym_ofs(op: tasmop; _op1: tasmsymbol; _op1ofs: longint);
- begin
- inherited Create(op);
- ops := 1;
- loadsymbol(0, _op1, _op1ofs);
- end;
- function taicpu.is_same_reg_move(regtype: Tregistertype): boolean;
- begin
- Result := (
- ((opcode = A_MOVE) and (regtype = R_INTREGISTER)) or
- ((regtype = R_FPUREGISTER) and (opcode in [A_MOV_S, A_MOV_D]))
- ) and
- (oper[0]^.reg = oper[1]^.reg);
- end;
- function taicpu.spilling_get_operation_type(opnr: longint): topertype;
- type
- op_write_set_type = set of TAsmOp;
- const
- op_write_set: op_write_set_type =
- [A_NEG,
- A_NEGU,
- A_LI,
- A_DLI,
- A_LA,
- A_MOVE,
- A_LB,
- A_LBU,
- A_LH,
- A_LHU,
- A_LW,
- A_LWU,
- A_LWL,
- A_LWR,
- A_LD,
- A_LDL,
- A_LDR,
- A_LL,
- A_LLD,
- A_ADDI,
- A_DADDI,
- A_ADDIU,
- A_DADDIU,
- A_SLTI,
- A_SLTIU,
- A_ANDI,
- A_ORI,
- A_XORI,
- A_LUI,
- A_DNEG,
- A_DNEGU,
- A_ADD,
- A_DADD,
- A_ADDU,
- A_DADDU,
- A_SUB,
- A_DSUB,
- A_SUBU,
- A_DSUBU,
- A_SLT,
- A_SLTU,
- A_AND,
- A_OR,
- A_XOR,
- A_NOR,
- A_MUL,
- A_MULO,
- A_MULOU,
- A_DMUL,
- A_DMULO,
- A_DMULOU,
- A_DIV,
- A_DIVU,
- A_DDIV,
- A_DDIVU,
- A_REM,
- A_REMU,
- A_DREM,
- A_DREMU,
- A_MULT,
- A_DMULT,
- A_MULTU,
- A_DMULTU,
- A_MFHI,
- A_MFLO,
- A_MULTG,
- A_DMULTG,
- A_MULTUG,
- A_DMULTUG,
- A_DIVG,
- A_DDIVG,
- A_DIVUG,
- A_DDIVUG,
- A_MODG,
- A_DMODG,
- A_MODUG,
- A_DMODUG,
- A_SLL,
- A_SRL,
- A_SRA,
- A_SLLV,
- A_SRLV,
- A_SRAV,
- A_DSLL,
- A_DSRL,
- A_DSRA,
- A_DSLLV,
- A_DSRLV,
- A_DSRAV,
- A_DSLL32,
- A_DSRL32,
- A_DSRA32,
- A_LWC1,
- A_LDC1,
- A_ADD_S,
- A_ADD_D,
- A_SUB_S,
- A_SUB_D,
- A_MUL_S,
- A_MUL_D,
- A_DIV_S,
- A_DIV_D,
- A_ABS_S,
- A_ABS_D,
- A_NEG_S,
- A_NEG_D,
- A_SQRT_S,
- A_SQRT_D,
- A_MOV_S,
- A_MOV_D,
- A_CVT_S_D,
- A_CVT_S_W,
- A_CVT_S_L,
- A_CVT_D_S,
- A_CVT_D_W,
- A_CVT_D_L,
- A_CVT_W_S,
- A_CVT_W_D,
- A_CVT_L_S,
- A_CVT_L_D,
- A_ROUND_W_S,
- A_ROUND_W_D,
- A_ROUND_L_S,
- A_ROUND_L_D,
- A_TRUNC_W_S,
- A_TRUNC_W_D,
- A_TRUNC_L_S,
- A_TRUNC_L_D,
- A_CEIL_W_S,
- A_CEIL_W_D,
- A_CEIL_L_S,
- A_CEIL_L_D,
- A_FLOOR_W_S,
- A_FLOOR_W_D,
- A_FLOOR_L_S,
- A_FLOOR_L_D,
- A_SEQ,
- A_SGE,
- A_SGEU,
- A_SGT,
- A_SGTU,
- A_SLE,
- A_SLEU,
- A_SNE];
- begin
- result := operand_read;
- if opcode in op_write_set then
- if opnr = 0 then
- result := operand_write;
- end;
- function spilling_create_load(const ref: treference; r: tregister): taicpu;
- begin
- case getregtype(r) of
- R_INTREGISTER :
- result:=taicpu.op_reg_ref(A_LW,r,ref);
- R_FPUREGISTER :
- begin
- case getsubreg(r) of
- R_SUBFS :
- result:=taicpu.op_reg_ref(A_LWC1,r,ref);
- R_SUBFD :
- result:=taicpu.op_reg_ref(A_LDC1,r,ref);
- else
- internalerror(200401042);
- end;
- end
- else
- internalerror(200401041);
- end;
- end;
- function spilling_create_store(r: tregister; const ref: treference): taicpu;
- begin
- case getregtype(r) of
- R_INTREGISTER :
- result:=taicpu.op_reg_ref(A_SW,r,ref);
- R_FPUREGISTER :
- begin
- case getsubreg(r) of
- R_SUBFS :
- result:=taicpu.op_reg_ref(A_SWC1,r,ref);
- R_SUBFD :
- result:=taicpu.op_reg_ref(A_SDC1,r,ref);
- else
- internalerror(200401042);
- end;
- end
- else
- internalerror(200401041);
- end;
- end;
- procedure InitAsm;
- begin
- end;
- procedure DoneAsm;
- begin
- end;
- begin
- cai_cpu := taicpu;
- cai_align := tai_align;
- end.
|