mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:09:27 +02:00
+ Xtensa: the boolean extension is used as flags
git-svn-id: trunk@44538 -
This commit is contained in:
parent
7cecc87441
commit
ba3de67f3b
@ -313,6 +313,7 @@
|
||||
{$define cpu32bitaddr}
|
||||
{$define cpu32bitalu}
|
||||
{$define cpufpemu}
|
||||
{$define cpuflags} { xtensa has a boolean extension }
|
||||
{$define cputargethasfixedstack}
|
||||
{$define cpuneedsmulhelper}
|
||||
{$define cpuneedsdivhelper}
|
||||
|
@ -220,6 +220,9 @@ interface
|
||||
{$elseif defined(sparcgen)}
|
||||
{ Load left node into flag F_NE/F_E }
|
||||
resflags.Init(NR_ICC,F_NE);
|
||||
{$elseif defined(xtensa)}
|
||||
{ Xtensa uses its own implementation }
|
||||
Internalerror(2020032901);
|
||||
{$else}
|
||||
{ Load left node into flag F_NE/F_E }
|
||||
resflags:=F_NE;
|
||||
|
@ -332,7 +332,11 @@ implementation
|
||||
LOC_FLAGS :
|
||||
begin
|
||||
cg.a_jmp_flags(list,p.location.resflags,truelabel);
|
||||
|
||||
{ e.g. xtensa has no default flags but uses a boolean register }
|
||||
{$if defined(NR_DEFAULTFLAGS)}
|
||||
cg.a_reg_dealloc(list,NR_DEFAULTFLAGS);
|
||||
{$endif defined(NR_DEFAULTFLAGS)}
|
||||
cg.a_jmp_always(list,falselabel);
|
||||
end;
|
||||
{$endif cpuflags}
|
||||
|
@ -57,7 +57,9 @@ interface
|
||||
|
||||
procedure a_call_name(list:TAsmList;const s:string; weak: boolean);override;
|
||||
procedure a_call_reg(list:TAsmList;Reg:tregister);override;
|
||||
|
||||
procedure a_jmp_name(list: TAsmList; const s: string);override;
|
||||
procedure a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);override;
|
||||
|
||||
procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe: boolean);override;
|
||||
procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe: boolean);override;
|
||||
@ -67,6 +69,8 @@ interface
|
||||
procedure a_cmp_reg_reg_label(list: TAsmList; size: tcgsize; cmp_op: topcmp; reg1, reg2: tregister; l: tasmlabel);override;
|
||||
procedure a_jmp_always(list: TAsmList; l: TAsmLabel);override;
|
||||
|
||||
procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);override;
|
||||
|
||||
procedure g_concatcopy(list : TAsmList; const source,dest : treference; len : tcgint);override;
|
||||
|
||||
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
||||
@ -546,6 +550,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgcpu.a_jmp_flags(list: TAsmList; const f: TResFlags; l: tasmlabel);
|
||||
var
|
||||
instr: taicpu;
|
||||
begin
|
||||
instr:=taicpu.op_reg_sym(A_Bcc,f.register,l);
|
||||
instr.condition:=flags_to_cond(f.flag);
|
||||
list.concat(instr);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgcpu.g_proc_entry(list : TAsmList; localsize : longint;
|
||||
nostackframe : boolean);
|
||||
var
|
||||
@ -773,6 +787,20 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgcpu.g_flags2reg(list: TAsmList; size: TCgSize; const f: tresflags; reg: TRegister);
|
||||
var
|
||||
hregister: TRegister;
|
||||
instr: taicpu;
|
||||
begin
|
||||
a_load_const_reg(list,size,0,reg);
|
||||
hregister:=getintregister(list,size);
|
||||
a_load_const_reg(list,size,1,hregister);
|
||||
instr:=taicpu.op_reg_reg_reg(A_MOV,reg,hregister,f.register);
|
||||
instr.condition:=flags_to_cond(f.flag);
|
||||
list.concat(instr);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgcpu.g_concatcopy_move(list: tasmlist; const Source, dest: treference; len: tcgint);
|
||||
var
|
||||
paraloc1, paraloc2, paraloc3: TCGPara;
|
||||
|
@ -78,7 +78,7 @@ unit cpubase;
|
||||
|
||||
{ Float Super register first and last }
|
||||
first_fpu_supreg = RS_F0;
|
||||
first_fpu_imreg = $08;
|
||||
first_fpu_imreg = $10;
|
||||
|
||||
{ MM Super register first and last }
|
||||
first_mm_supreg = RS_INVALID;
|
||||
@ -109,18 +109,27 @@ unit cpubase;
|
||||
C_GE,C_LT,C_GEU,C_LTU,
|
||||
C_ANY,C_BNONE,C_ALL,C_NALL,C_BC,C_BS,
|
||||
C_EQZ,C_NEZ,C_LTZ,C_GEZ,
|
||||
C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI
|
||||
C_EQI,C_NEI,C_LTI,C_GEI,C_LTUI,C_GEUI,
|
||||
C_F,C_T
|
||||
);
|
||||
|
||||
TAsmConds = set of TAsmCond;
|
||||
|
||||
TResFlagsEnum = (F_Z,F_NZ);
|
||||
|
||||
TResFlags = record
|
||||
register: TRegister;
|
||||
flag: TResFlagsEnum;
|
||||
end;
|
||||
|
||||
const
|
||||
cond2str : array[TAsmCond] of string[4]=('',
|
||||
'eq','ne',
|
||||
'ge','lt','geu','ltu',
|
||||
'any','none','all','nall','bc','bs',
|
||||
'eqz','nez','ltz','gez',
|
||||
'eqi','nei','lti','gei','ltui','geui'
|
||||
'eqi','nei','lti','gei','ltui','geui',
|
||||
'f','t'
|
||||
);
|
||||
|
||||
uppercond2str : array[TAsmCond] of string[4]=('',
|
||||
@ -128,7 +137,8 @@ unit cpubase;
|
||||
'GE','LT','GEU','LTU',
|
||||
'ANY','NONE','ALL','NALL','BC','BS',
|
||||
'EQZ','NEZ','LTZ','GEZ',
|
||||
'EQI','NEI','LTI','GEI','LTUI','GEUI'
|
||||
'EQI','NEI','LTI','GEI','LTUI','GEUI',
|
||||
'F','T'
|
||||
);
|
||||
|
||||
{*****************************************************************************
|
||||
@ -246,6 +256,8 @@ unit cpubase;
|
||||
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
|
||||
|
||||
{ Checks if Subset is a subset of c (e.g. "less than" is a subset of "less than or equal" }
|
||||
function condition_in(const Subset, c: TAsmCond): Boolean;
|
||||
|
||||
@ -361,13 +373,23 @@ unit cpubase;
|
||||
C_BNONE,C_ANY,C_NALL,C_BNONE,C_BS,C_BC,
|
||||
|
||||
C_NEZ,C_EQZ,C_GEZ,C_LTZ,
|
||||
C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI
|
||||
C_NEI,C_EQI,C_GEI,C_LTI,C_GEUI,C_LTUI,
|
||||
C_T,C_F
|
||||
);
|
||||
begin
|
||||
result := inverse[c];
|
||||
end;
|
||||
|
||||
|
||||
function flags_to_cond(const f: TResFlagsEnum) : TAsmCond;
|
||||
const flags2cond: array[TResFlagsEnum] of tasmcond = (
|
||||
C_F,
|
||||
C_T);
|
||||
begin
|
||||
flags_to_cond := flags2cond[f];
|
||||
end;
|
||||
|
||||
|
||||
function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
result := c1 = c2;
|
||||
|
Loading…
Reference in New Issue
Block a user