summaryrefslogtreecommitdiff
path: root/compiler/mips/cgcpu.pas
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-01-21 23:28:34 +0000
commit1903b037de2fb3e75826406b46f055acb70963fa (patch)
tree604cd8b790fe14e5fbe441d4cd647c80d2a36a9a /compiler/mips/cgcpu.pas
parentad1141d52f8353457053b925cd674fe1d5c4eafc (diff)
parent953d907e4d6c3a5c2f8aaee6e5e4f73c55ce5985 (diff)
downloadfpc-blocks.tar.gz
* synchronised with trunk till r29513blocks
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/blocks@29516 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/mips/cgcpu.pas')
-rw-r--r--compiler/mips/cgcpu.pas131
1 files changed, 90 insertions, 41 deletions
diff --git a/compiler/mips/cgcpu.pas b/compiler/mips/cgcpu.pas
index cdc8d213b2..79e4a68975 100644
--- a/compiler/mips/cgcpu.pas
+++ b/compiler/mips/cgcpu.pas
@@ -197,16 +197,9 @@ begin
{ PIC global symbol }
ref.symbol:=nil;
- if (ref.offset=0) then
- exit;
-
if (ref.offset>=simm16lo) and
(ref.offset<=simm16hi-sizeof(pint)) then
- begin
- list.concat(taicpu.op_reg_reg_const(A_ADDIU,ref.base,ref.base,ref.offset));
- ref.offset:=0;
- exit;
- end;
+ exit;
{ fallthrough to the case of large offset }
end;
@@ -295,10 +288,6 @@ begin
[RS_F0,RS_F2,RS_F4,RS_F6, RS_F8,RS_F10,RS_F12,RS_F14,
RS_F16,RS_F18,RS_F20,RS_F22, RS_F24,RS_F26,RS_F28,RS_F30],
first_fpu_imreg, []);
-
- { needs at least one element for rgobj not to crash }
- rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
- [RS_R0],first_mm_imreg,[]);
end;
@@ -307,7 +296,6 @@ procedure TCGMIPS.done_register_allocators;
begin
rg[R_INTREGISTER].Free;
rg[R_FPUREGISTER].Free;
- rg[R_MMREGISTER].Free;
inherited done_register_allocators;
end;
@@ -441,7 +429,7 @@ end;
procedure TCGMIPS.a_load_const_reg(list: tasmlist; size: TCGSize; a: tcgint; reg: TRegister);
begin
if (a = 0) then
- list.concat(taicpu.op_reg_reg(A_MOVE, reg, NR_R0))
+ a_load_reg_reg(list, OS_INT, OS_INT, NR_R0, reg)
else if (a >= simm16lo) and (a <= simm16hi) then
list.concat(taicpu.op_reg_reg_const(A_ADDIU, reg, NR_R0, a))
else if (a>=0) and (a <= 65535) then
@@ -546,13 +534,23 @@ begin
done:=false;
OS_S8:
begin
- list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 24));
- list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 24));
+ if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) then
+ list.concat(taicpu.op_reg_reg(A_SEB,reg2,reg1))
+ else
+ begin
+ list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 24));
+ list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 24));
+ end;
end;
OS_S16:
begin
- list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 16));
- list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 16));
+ if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) then
+ list.concat(taicpu.op_reg_reg(A_SEH,reg2,reg1))
+ else
+ begin
+ list.concat(taicpu.op_reg_reg_const(A_SLL, reg2, reg1, 16));
+ list.concat(taicpu.op_reg_reg_const(A_SRA, reg2, reg2, 16));
+ end;
end;
else
internalerror(2002090901);
@@ -820,6 +818,7 @@ var
hreg: TRegister;
asmop: TAsmOp;
begin
+ a:=aint(a);
ovloc.loc := LOC_VOID;
optimize_op_const(size,op,a);
signed:=(size in [OS_S8,OS_S16,OS_S32]);
@@ -935,23 +934,30 @@ begin
end;
OP_MUL,OP_IMUL:
begin
- list.concat(taicpu.op_reg_reg(TOpCg2AsmOp[op], src2, src1));
- list.concat(taicpu.op_reg(A_MFLO, dst));
- if setflags then
+ if (CPUMIPS_HAS_ISA32R2 in cpu_capabilities[current_settings.cputype]) and
+ (not setflags) then
+ { NOTE: MUL is actually mips32r1 instruction; on older cores it is handled as macro }
+ list.concat(taicpu.op_reg_reg_reg(A_MUL,dst,src2,src1))
+ else
begin
- current_asmdata.getjumplabel(hl);
- hreg:=GetIntRegister(list,OS_INT);
- list.concat(taicpu.op_reg(A_MFHI,hreg));
- if (op=OP_IMUL) then
+ list.concat(taicpu.op_reg_reg(TOpCg2AsmOp[op], src2, src1));
+ list.concat(taicpu.op_reg(A_MFLO, dst));
+ if setflags then
begin
- hreg2:=GetIntRegister(list,OS_INT);
- list.concat(taicpu.op_reg_reg_const(A_SRA,hreg2,dst,31));
- a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg2,hreg,hl);
- end
- else
- a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg,NR_R0,hl);
- list.concat(taicpu.op_const(A_BREAK,6));
- a_label(list,hl);
+ current_asmdata.getjumplabel(hl);
+ hreg:=GetIntRegister(list,OS_INT);
+ list.concat(taicpu.op_reg(A_MFHI,hreg));
+ if (op=OP_IMUL) then
+ begin
+ hreg2:=GetIntRegister(list,OS_INT);
+ list.concat(taicpu.op_reg_reg_const(A_SRA,hreg2,dst,31));
+ a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg2,hreg,hl);
+ end
+ else
+ a_cmp_reg_reg_label(list,OS_INT,OC_EQ,hreg,NR_R0,hl);
+ list.concat(taicpu.op_const(A_BREAK,6));
+ a_label(list,hl);
+ end;
end;
end;
OP_AND,OP_OR,OP_XOR:
@@ -1071,7 +1077,28 @@ end;
procedure TCGMIPS.a_jmp_flags(list: tasmlist; const f: TResFlags; l: tasmlabel);
+ var
+ ai: taicpu;
begin
+ case f.reg1 of
+ NR_FCC0..NR_FCC7:
+ begin
+ if (f.reg1=NR_FCC0) then
+ ai:=taicpu.op_sym(A_BC,l)
+ else
+ ai:=taicpu.op_reg_sym(A_BC,f.reg1,l);
+ list.concat(ai);
+ { delay slot }
+ list.concat(taicpu.op_none(A_NOP));
+ case f.cond of
+ OC_NE: ai.SetCondition(C_COP1TRUE);
+ OC_EQ: ai.SetCondition(C_COP1FALSE);
+ else
+ InternalError(2014082901);
+ end;
+ exit;
+ end;
+ end;
if f.use_const then
a_cmp_const_reg_label(list,OS_INT,f.cond,f.value,f.reg1,l)
else
@@ -1083,7 +1110,33 @@ procedure TCGMIPS.g_flags2reg(list: tasmlist; size: tcgsize; const f: tresflags;
var
left,right: tregister;
unsigned: boolean;
+ hl: tasmlabel;
begin
+ case f.reg1 of
+ NR_FCC0..NR_FCC7:
+ begin
+ if (current_settings.cputype>=cpu_mips4) then
+ begin
+ a_load_const_reg(list,size,1,reg);
+ case f.cond of
+ OC_NE: list.concat(taicpu.op_reg_reg_reg(A_MOVF,reg,NR_R0,f.reg1));
+ OC_EQ: list.concat(taicpu.op_reg_reg_reg(A_MOVT,reg,NR_R0,f.reg1));
+ else
+ InternalError(2014082902);
+ end;
+ end
+ else
+ begin
+ { TODO: still possible to do branchless by extracting appropriate bit from FCSR? }
+ current_asmdata.getjumplabel(hl);
+ a_load_const_reg(list,size,1,reg);
+ a_jmp_flags(list,f,hl);
+ a_load_const_reg(list,size,0,reg);
+ a_label(list,hl);
+ end;
+ exit;
+ end;
+ end;
if (f.cond in [OC_EQ,OC_NE]) then
begin
left:=reg;
@@ -1212,7 +1265,6 @@ var
largeoffs : boolean;
begin
list.concat(tai_directive.create(asd_ent,current_procinfo.procdef.mangledname));
- a_reg_alloc(list,NR_STACK_POINTER_REG);
if nostackframe then
begin
@@ -1221,9 +1273,6 @@ begin
exit;
end;
- if (pi_needs_stackframe in current_procinfo.flags) then
- a_reg_alloc(list,NR_FRAME_POINTER_REG);
-
helplist:=TAsmList.Create;
reference_reset(href,0);
@@ -1236,7 +1285,7 @@ begin
begin
if reg in (rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall)) then
begin
- fmask:=fmask or (1 shl ord(reg));
+ fmask:=fmask or (longword(1) shl ord(reg));
href.offset:=nextoffset;
lastfpuoffset:=nextoffset;
helplist.concat(taicpu.op_reg_ref(A_SWC1,newreg(R_FPUREGISTER,reg,R_SUBFS),href));
@@ -1266,7 +1315,7 @@ begin
begin
if reg in saveregs then
begin
- mask:=mask or (1 shl ord(reg));
+ mask:=mask or (longword(1) shl ord(reg));
href.offset:=nextoffset;
lastintoffset:=nextoffset;
if (reg=RS_FRAME_POINTER_REG) then
@@ -1282,8 +1331,8 @@ begin
//list.concat(Taicpu.Op_reg_reg_const(A_ADDIU,NR_FRAME_POINTER_REG,NR_STACK_POINTER_REG,current_procinfo.para_stack_size));
list.concat(Taicpu.op_none(A_P_SET_NOMIPS16));
list.concat(Taicpu.op_reg_const_reg(A_P_FRAME,current_procinfo.framepointer,LocalSize,NR_R31));
- list.concat(Taicpu.op_const_const(A_P_MASK,mask,-(LocalSize-lastintoffset)));
- list.concat(Taicpu.op_const_const(A_P_FMASK,Fmask,-(LocalSize-lastfpuoffset)));
+ list.concat(Taicpu.op_const_const(A_P_MASK,aint(mask),-(LocalSize-lastintoffset)));
+ list.concat(Taicpu.op_const_const(A_P_FMASK,aint(Fmask),-(LocalSize-lastfpuoffset)));
list.concat(Taicpu.op_none(A_P_SET_NOREORDER));
if (cs_create_pic in current_settings.moduleswitches) and
(pi_needs_got in current_procinfo.flags) then