mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 11:29:24 +02:00
+ MIPS: Use INS and EXT instructions for bit manipulations when target CPU type is set to mips32r2.
git-svn-id: trunk@25029 -
This commit is contained in:
parent
eb1ff90de1
commit
d0ae800da6
@ -56,6 +56,8 @@ type
|
||||
|
||||
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);
|
||||
{ INS and EXT }
|
||||
constructor op_reg_reg_const_const(op: tasmop; _op1,_op2: tregister; _op3,_op4: aint);
|
||||
constructor op_reg_const_reg(op: tasmop; _op1: tregister; _op2: aint; _op3: tregister);
|
||||
|
||||
{ this is for Jmp instructions }
|
||||
@ -186,6 +188,17 @@ begin
|
||||
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_const_reg(op: tasmop; _op1: tregister; _op2: aint;
|
||||
_op3: tregister);
|
||||
begin
|
||||
@ -385,7 +398,10 @@ end;
|
||||
A_SGTU,
|
||||
A_SLE,
|
||||
A_SLEU,
|
||||
A_SNE];
|
||||
A_SNE,
|
||||
A_EXT,
|
||||
A_INS,
|
||||
A_MFC0];
|
||||
|
||||
begin
|
||||
result := operand_read;
|
||||
|
@ -38,6 +38,9 @@ uses
|
||||
type
|
||||
thlcgmips = class(thlcg2ll)
|
||||
function a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef; weak: boolean): tcgpara; override;
|
||||
procedure a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister);override;
|
||||
protected
|
||||
procedure a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt); override;
|
||||
end;
|
||||
|
||||
procedure create_hlcodegen;
|
||||
@ -45,11 +48,15 @@ uses
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,
|
||||
aasmtai,
|
||||
aasmcpu,
|
||||
cutils,
|
||||
globals,
|
||||
defutil,
|
||||
cgobj,
|
||||
cpubase,
|
||||
cpuinfo,
|
||||
cgcpu;
|
||||
|
||||
function thlcgmips.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; forceresdef: tdef; weak: boolean): tcgpara;
|
||||
@ -79,6 +86,66 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure thlcgmips.a_load_subsetreg_reg(list: TAsmList; subsetsize, tosize: tdef; const sreg: tsubsetregister; destreg: tregister);
|
||||
var
|
||||
cgsubsetsize,
|
||||
cgtosize: tcgsize;
|
||||
begin
|
||||
cgsubsetsize:=def_cgsize(subsetsize);
|
||||
cgtosize:=def_cgsize(tosize);
|
||||
if (current_settings.cputype<>cpu_mips32r2) then
|
||||
inherited a_load_subsetreg_reg(list,subsetsize,tosize,sreg,destreg)
|
||||
else if (sreg.bitlen>32) then
|
||||
InternalError(2013070201)
|
||||
else if (sreg.bitlen<>32) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg_reg_const_const(A_EXT,destreg,sreg.subsetreg,
|
||||
sreg.startbit,sreg.bitlen));
|
||||
{ types with a negative lower bound are always a base type (8, 16, 32 bits) }
|
||||
if (cgsubsetsize in [OS_S8..OS_S128]) then
|
||||
if ((sreg.bitlen mod 8) = 0) then
|
||||
begin
|
||||
cg.a_load_reg_reg(list,tcgsize2unsigned[cgsubsetsize],cgsubsetsize,destreg,destreg);
|
||||
cg.a_load_reg_reg(list,cgsubsetsize,cgtosize,destreg,destreg);
|
||||
end
|
||||
else
|
||||
begin
|
||||
cg.a_op_const_reg(list,OP_SHL,OS_INT,32-sreg.bitlen,destreg);
|
||||
cg.a_op_const_reg(list,OP_SAR,OS_INT,32-sreg.bitlen,destreg);
|
||||
end;
|
||||
end
|
||||
else
|
||||
cg.a_load_reg_reg(list,cgsubsetsize,cgtosize,sreg.subsetreg,destreg);
|
||||
end;
|
||||
|
||||
|
||||
procedure thlcgmips.a_load_regconst_subsetreg_intern(list: TAsmList; fromsize, subsetsize: tdef; fromreg: tregister; const sreg: tsubsetregister; slopt: tsubsetloadopt);
|
||||
begin
|
||||
if (current_settings.cputype<>cpu_mips32r2) then
|
||||
inherited a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,sreg,slopt)
|
||||
else if (sreg.bitlen>32) then
|
||||
InternalError(2013070202)
|
||||
else if (sreg.bitlen<>32) then
|
||||
begin
|
||||
case slopt of
|
||||
SL_SETZERO:
|
||||
fromreg:=NR_R0;
|
||||
SL_SETMAX:
|
||||
begin
|
||||
fromreg:=cg.getintregister(list,OS_INT);
|
||||
cg.a_load_const_reg(list,OS_INT,-1,fromreg);
|
||||
end;
|
||||
end;
|
||||
list.concat(taicpu.op_reg_reg_const_const(A_INS,sreg.subsetreg,fromreg,
|
||||
sreg.startbit,sreg.bitlen));
|
||||
end
|
||||
else if not (slopt in [SL_SETZERO,SL_SETMAX]) then
|
||||
cg.a_load_reg_reg(list,def_cgsize(fromsize),def_cgsize(subsetsize),fromreg,sreg.subsetreg)
|
||||
else
|
||||
inherited a_load_regconst_subsetreg_intern(list,fromsize,subsetsize,fromreg,sreg,slopt);
|
||||
end;
|
||||
|
||||
|
||||
procedure create_hlcodegen;
|
||||
begin
|
||||
hlcg:=thlcgmips.create;
|
||||
|
Loading…
Reference in New Issue
Block a user