* today's arm patches

This commit is contained in:
florian 2003-08-28 00:05:29 +00:00
parent f04bddec4a
commit dc7d8ba847
6 changed files with 321 additions and 80 deletions

View File

@ -155,6 +155,7 @@ implementation
loadreg(1,_op2);
end;
constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
begin
inherited create(op);
@ -201,6 +202,7 @@ implementation
loadreg(2,_op3);
end;
constructor taicpu.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
begin
inherited create(op);
@ -214,6 +216,7 @@ implementation
loadconst(2,aword(_op3));
end;
constructor taicpu.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint);
begin
inherited create(op);
@ -318,6 +321,7 @@ implementation
loadconst(4,cardinal(_op5));
end;
constructor taicpu.op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
begin
inherited create(op);
@ -333,6 +337,7 @@ implementation
loadconst(4,cardinal(_op5));
end;
constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
begin
inherited create(op);
@ -341,6 +346,7 @@ implementation
loadsymbol(0,_op1,0);
end;
constructor taicpu.op_const_const_sym(op : tasmop;_op1,_op2 : longint; _op3: tasmsymbol);
begin
inherited create(op);
@ -406,7 +412,8 @@ implementation
r:Tsupregset;
var unusedregsint:Tsupregset;
const spilltemplist:Tspill_temp_list): boolean;
{$ifdef dummy}
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister):Tai;
var back:Tsupregset;
@ -466,63 +473,11 @@ implementation
result := true;
wasload := true;
case op of
A_LBZ:
A_LDR:
begin
counterpart := A_STB;
counterpart := A_STR;
end;
A_LBZX:
begin
counterpart := A_STBX;
end;
A_LHZ,A_LHA:
begin
counterpart := A_STH;
end;
A_LHZX,A_LHAX:
begin
counterpart := A_STHX;
end;
A_LWZ:
begin
counterpart := A_STW;
end;
A_LWZX:
begin
counterpart := A_STWX;
end;
A_STB:
begin
counterpart := A_LBZ;
wasload := false;
end;
A_STBX:
begin
counterpart := A_LBZX;
wasload := false;
end;
A_STH:
begin
counterpart := A_LHZ;
wasload := false;
end;
A_STHX:
begin
counterpart := A_LHZX;
wasload := false;
end;
A_STW:
begin
counterpart := A_LWZ;
wasload := false;
end;
A_STWX:
begin
counterpart := A_LWZX;
wasload := false;
end;
A_LBZU,A_LBZUX,A_LHZU,A_LHZUX,A_LHAU,A_LHAUX,
A_LWZU,A_LWZUX,A_STBU,A_STBUX,A_STHU,A_STHUX,
A_STWU,A_STWUX:
A_LDM:
internalerror(2003070602);
else
result := false;
@ -602,7 +557,7 @@ implementation
pos:=get_insert_pos(Tai(previous),oper[1].ref^.index.number shr 8,0,0);
rgget(list,pos,0,helpreg);
spill_registers:=true;
helpins:=Taicpu.op_reg_ref(A_LWZ,helpreg,spilltemplist[supreg]);
helpins:=Taicpu.op_reg_ref(A_LDR,helpreg,spilltemplist[supreg]);
if pos=nil then
list.insertafter(helpins,list.first)
else
@ -626,7 +581,7 @@ implementation
pos:=get_insert_pos(Tai(previous),oper[1].ref^.base.number shr 8,0,0);
rgget(list,pos,0,helpreg);
spill_registers:=true;
helpins:=Taicpu.op_reg_ref(A_LWZ,helpreg,spilltemplist[supreg]);
helpins:=Taicpu.op_reg_ref(A_LDR,helpreg,spilltemplist[supreg]);
if pos=nil then
list.insertafter(helpins,list.first)
else
@ -675,9 +630,9 @@ implementation
pos := get_insert_pos(Tai(previous),reg1,reg2,reg3);
rgget(list,pos,0,helpreg);
spill_registers := true;
helpins := taicpu.op_reg_ref(A_STW,helpreg,spilltemplist[supreg]);
helpins := taicpu.op_reg_ref(A_STR,helpreg,spilltemplist[supreg]);
list.insertafter(helpins,self);
helpins := taicpu.op_reg_ref(A_LWZ,helpreg,spilltemplist[supreg]);
helpins := taicpu.op_reg_ref(A_LDR,helpreg,spilltemplist[supreg]);
if pos=nil then
list.insertafter(helpins,list.first)
else
@ -709,7 +664,7 @@ implementation
pos := get_insert_pos(Tai(previous),reg1,reg2,reg3);
rgget(list,pos,0,helpreg);
spill_registers := true;
helpins := taicpu.op_reg_ref(A_LWZ,helpreg,spilltemplist[supreg]);
helpins := taicpu.op_reg_ref(A_LDR,helpreg,spilltemplist[supreg]);
if pos=nil then
list.insertafter(helpins,list.first)
else
@ -724,10 +679,6 @@ implementation
end;
end;
end;
{$else dummy}
begin
end;
{$endif dummy}
procedure InitAsm;
@ -742,7 +693,10 @@ implementation
end.
{
$Log$
Revision 1.5 2003-08-27 00:27:56 florian
Revision 1.6 2003-08-28 00:05:29 florian
* today's arm patches
Revision 1.5 2003/08/27 00:27:56 florian
+ same procedure as very day: today's work on arm
Revision 1.4 2003/08/25 23:20:38 florian

View File

@ -100,10 +100,6 @@ unit agarmgas;
s:=s+tostr(offset);
end;
if (index.enum < firstreg) or (index.enum > lastreg) then
internalerror(20030312);
if (base.enum < firstreg) or (base.enum > lastreg) then
internalerror(200303123);
if (index.enum=R_NO) and (base.enum<>R_NO) then
begin
if offset=0 then
@ -113,7 +109,10 @@ unit agarmgas;
else
s:=s+'0';
end;
s:=s+'['+std_reg2str[base.enum]+']'
if base.enum=R_INTREGISTER then
s:=s+'('+gas_regname(base.number)+')'
else
s:=s+'('+gas_reg2str[base.enum]+')';
end
else if (index.enum<>R_NO) and (base.enum<>R_NO) and (offset=0) then
s:=s+std_reg2str[base.enum]+','+std_reg2str[index.enum]
@ -175,12 +174,23 @@ unit agarmgas;
case o.typ of
top_reg:
begin
if (o.reg.enum < R_R0) or (o.reg.enum > lastreg) then
internalerror(200303125);
getopstr:=std_reg2str[o.reg.enum];
if o.reg.enum=R_INTREGISTER then
getopstr:=gas_regname(o.reg.number)
else
getopstr:=gas_reg2str[o.reg.enum];
end;
top_shifterop:
begin
if (o.shifterop^.rs.enum<>R_NO) and (o.shifterop^.shiftimm=0) then
begin
if o.shifterop^.rs.enum=R_INTREGISTER then
getopstr:=shifterop2str[o.shifterop^.shiftertype]+' '+gas_regname(o.shifterop^.rs.number)
else
getopstr:=shifterop2str[o.shifterop^.shiftertype]+' '+gas_reg2str[o.shifterop^.rs.enum];
end
else if (o.shifterop^.rs.enum=R_NO) then
getopstr:=shifterop2str[o.shifterop^.shiftertype]+' #'+tostr(o.shifterop^.shiftimm)
else internalerror(200308282);
end;
top_const:
getopstr:=tostr(longint(o.val));
@ -263,7 +273,16 @@ unit agarmgas;
function gas_regname(const r:Tnewregister):string;
var s:Tsuperregister;
begin
s:=r shr 8;
if s in [RS_R0..RS_R15] then
gas_regname:='r'+tostr(s-RS_R0)
else
begin
{Generate a systematic name.}
gas_regname:='reg'+tostr(s)+'d';
end;
end;
@ -273,7 +292,10 @@ begin
end.
{
$Log$
Revision 1.3 2003-08-24 12:27:26 florian
Revision 1.4 2003-08-28 00:05:29 florian
* today's arm patches
Revision 1.3 2003/08/24 12:27:26 florian
* continued to work on the arm port
Revision 1.2 2003/08/20 15:50:12 florian

View File

@ -272,6 +272,7 @@ unit cgcpu;
procedure tcgarm.a_op_reg_reg(list : taasmoutput; Op: TOpCG; size: TCGSize; src, dst: TRegister);
begin
a_op_reg_reg_reg(list,op,OS_32,src,dst,dst);
end;
@ -283,7 +284,44 @@ unit cgcpu;
procedure tcgarm.a_op_reg_reg_reg(list: taasmoutput; op: TOpCg;
size: tcgsize; src1, src2, dst: tregister);
const
op_reg_reg_opcg2asmop: array[TOpCG] of tasmop =
(A_NONE,A_ADD,A_AND,A_NONE,A_NONE,A_MUL,A_MUL,A_NONE,A_NONE,A_ORR,
A_NONE,A_NONE,A_NONE,A_SUB,A_EOR);
var
so : tshifterop;
begin
case op of
OP_NEG:
list.concat(taicpu.op_reg_reg(op_reg_reg_opcg2asmop[op],dst,dst));
OP_NOT:
list.concat(taicpu.op_reg_reg(A_MVN,dst,dst));
OP_DIV,OP_IDIV:
internalerror(200308281);
OP_SHL:
begin
shifterop_reset(so);
so.rs:=src2;
so.shiftertype:=SO_LSL;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src1,so));
end;
OP_SHR:
begin
shifterop_reset(so);
so.rs:=src2;
so.shiftertype:=SO_LSR;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src1,so));
end;
OP_SAR:
begin
shifterop_reset(so);
so.rs:=src2;
so.shiftertype:=SO_LSL;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src1,so));
end;
else
list.concat(taicpu.op_reg_reg_reg(op_reg_reg_opcg2asmop[op],dst,src2,src1));
end;
end;
@ -345,7 +383,61 @@ unit cgcpu;
procedure tcgarm.a_load_reg_reg(list : taasmoutput; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
var
instr: taicpu;
so : tshifterop;
begin
shifterop_reset(so);
if (reg1.enum<>R_INTREGISTER) or (reg1.number = 0) then
internalerror(200303101);
if (reg2.enum<>R_INTREGISTER) or (reg2.number = 0) then
internalerror(200303102);
if (reg1.number<>reg2.number) or
(tcgsize2size[tosize] < tcgsize2size[fromsize]) or
((tcgsize2size[tosize] = tcgsize2size[fromsize]) and
(tosize <> fromsize) and
not(fromsize in [OS_32,OS_S32])) then
begin
case tosize of
OS_8:
instr := taicpu.op_reg_reg_const(A_AND,
reg2,reg1,$ff);
OS_S8:
begin
so.shiftertype:=SO_LSL;
so.shiftimm:=24;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg1,so));
so.shiftertype:=SO_ASR;
so.shiftimm:=24;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg2,so));
end;
OS_16:
begin
so.shiftertype:=SO_LSL;
so.shiftimm:=16;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg1,so));
so.shiftertype:=SO_LSR;
so.shiftimm:=16;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg2,so));
end;
OS_S16:
begin
so.shiftertype:=SO_LSL;
so.shiftimm:=16;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg1,so));
so.shiftertype:=SO_ASR;
so.shiftimm:=16;
list.concat(taicpu.op_reg_reg_shifterop(A_MOV,reg2,reg2,so));
end;
OS_32,OS_S32:
begin
instr:=taicpu.op_reg_reg(A_MOV,reg2,reg1);
rg.add_move_instruction(instr);
list.concat(instr);
end;
else internalerror(2002090901);
end;
end;
end;
@ -383,7 +475,13 @@ unit cgcpu;
procedure tcgarm.a_jmp_flags(list : taasmoutput;const f : TResFlags;l: tasmlabel);
var
ai : taicpu;
begin
ai := Taicpu.op_sym(A_B,l);
ai.SetCondition(flags_to_cond(f));
ai.is_jmp := true;
list.concat(ai);
end;
@ -493,7 +591,10 @@ begin
end.
{
$Log$
Revision 1.5 2003-08-25 23:20:38 florian
Revision 1.6 2003-08-28 00:05:29 florian
* today's arm patches
Revision 1.5 2003/08/25 23:20:38 florian
+ started to implement FPU support for the ARM
* fixed a lot of other things

View File

@ -612,10 +612,17 @@ uses
procedure shifterop_reset(var so : tshifterop);
implementation
implementation
uses
verbose;
procedure convert_register_to_enum(var r:Tregister);
begin
if r.enum = R_INTREGISTER then
r.enum := toldregister(r.number shr 8)
else
internalerror(200308271);
end;
@ -643,14 +650,37 @@ implementation
function flags_to_cond(const f: TResFlags) : TAsmCond;
const
flag_2_cond: array[F_EQ..F_LE] of TAsmCond =
(C_EQ,C_NE,C_CS,C_CC,C_MI,C_PL,C_VS,C_VC,C_HI,C_LS,
C_GE,C_LT,C_GT,C_LE);
begin
if f>high(flag_2_cond) then
internalerror(200112301);
result:=flag_2_cond[f];
end;
function supreg_name(r:Tsuperregister):string;
const
supreg_names:array[0..last_supreg] of string[3]=
('inv',
'r0' ,'r2', 'r3','r4','r5','r6','r7','r8',
'r8' ,'r9', 'r10','r11','r12','r13','r14','pc'
);
var
s : string[4];
begin
if r in [0..last_supreg] then
supreg_name:=supreg_names[r]
else
begin
str(r,s);
supreg_name:='reg'+s;
end;
end;
procedure shifterop_reset(var so : tshifterop);
begin
FillChar(so,sizeof(so),0);
@ -660,7 +690,10 @@ implementation
end.
{
$Log$
Revision 1.7 2003-08-25 23:20:38 florian
Revision 1.8 2003-08-28 00:05:29 florian
* today's arm patches
Revision 1.7 2003/08/25 23:20:38 florian
+ started to implement FPU support for the ARM
* fixed a lot of other things

View File

@ -38,14 +38,17 @@ unit cpunode;
narmadd,
narmcal,
narmmat,
//!!! narminl,
narminl,
narmcnv
;
end.
{
$Log$
Revision 1.6 2003-08-27 00:27:56 florian
Revision 1.7 2003-08-28 00:05:29 florian
* today's arm patches
Revision 1.6 2003/08/27 00:27:56 florian
+ same procedure as very day: today's work on arm
Revision 1.5 2003/08/25 23:20:38 florian

128
compiler/arm/narminl.pas Normal file
View File

@ -0,0 +1,128 @@
{
$Id$
Copyright (c) 1998-2002 by Florian Klaempfl
Generates ARM inline nodes
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 narminl;
{$i fpcdefs.inc}
interface
uses
node,ninl,ncginl;
type
tarminlinenode = class(tcgInlineNode)
function first_abs_real: tnode; override;
function first_sqr_real: tnode; override;
function first_sqrt_real: tnode; override;
procedure second_abs_real; override;
procedure second_sqr_real; override;
procedure second_sqrt_real; override;
private
procedure load_fpu_location;
end;
implementation
uses
globtype,systems,
cutils,verbose,globals,fmodule,
symconst,symdef,
aasmbase,aasmtai,aasmcpu,
cginfo,cgbase,pass_1,pass_2,
cpubase,paramgr,
nbas,ncon,ncal,ncnv,nld,
tgobj,ncgutil,cgobj,cg64f32,rgobj,rgcpu;
{*****************************************************************************
tarminlinenode
*****************************************************************************}
procedure tarminlinenode.load_fpu_location;
begin
secondpass(left);
location_force_fpureg(exprasmlist,left.location,true);
location_copy(location,left.location);
if left.location.loc=LOC_CFPUREGISTER then
begin
location.register:=rg.getregisterfpu(exprasmlist,location.size);
location.loc := LOC_FPUREGISTER;
end;
end;
function tarminlinenode.first_abs_real : tnode;
begin
expectloc:=LOC_FPUREGISTER;
registers32:=left.registers32;
registersfpu:=max(left.registersfpu,1);
first_abs_real := nil;
end;
function tarminlinenode.first_sqr_real : tnode;
begin
expectloc:=LOC_FPUREGISTER;
registers32:=left.registers32;
registersfpu:=max(left.registersfpu,1);
first_sqr_real:=nil;
end;
function tarminlinenode.first_sqrt_real : tnode;
begin
expectloc:=LOC_FPUREGISTER;
registers32:=left.registers32;
registersfpu:=max(left.registersfpu,1);
first_sqrt_real := nil;
end;
procedure tarminlinenode.second_abs_real;
begin
load_fpu_location;
exprasmlist.concat(taicpu.op_reg(A_ABS,location.register));
end;
procedure tarminlinenode.second_sqr_real;
begin
load_fpu_location;
exprasmlist.concat(taicpu.op_reg_reg(A_MUF,location.register,left.location.register));
end;
procedure tarminlinenode.second_sqrt_real;
begin
load_fpu_location;
exprasmlist.concat(taicpu.op_reg(A_SQT,location.register));
end;
begin
cinlinenode:=tarminlinenode;
end.
{
$Log$
Revision 1.1 2003-08-28 00:05:29 florian
* today's arm patches
}