diff --git a/compiler/systems/i_embed.pas b/compiler/systems/i_embed.pas index ce0097c12b..14088fb803 100644 --- a/compiler/systems/i_embed.pas +++ b/compiler/systems/i_embed.pas @@ -704,14 +704,14 @@ unit i_embed; varalignmin : 0; varalignmax : 4; localalignmin : 4; - localalignmax : 4; + localalignmax : 16; recordalignmin : 0; recordalignmax : 4; maxCrecordalign : 4 ); first_parm_offset : 8; - stacksize : 262144; - stackalign : 4; + stacksize : 65536; + stackalign : 16; abi : abi_default; llvmdatalayout : 'e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32-S32'; ); diff --git a/compiler/xtensa/cgcpu.pas b/compiler/xtensa/cgcpu.pas index 9edc79ccb0..8537f94f64 100644 --- a/compiler/xtensa/cgcpu.pas +++ b/compiler/xtensa/cgcpu.pas @@ -508,10 +508,78 @@ implementation procedure tcgcpu.g_proc_entry(list : TAsmList; localsize : longint; - nostackframe : boolean); + nostackframe : boolean); + var + ref : treference; + r : byte; + regs : tcpuregisterset; + stackmisalignment : pint; + regoffset : LongInt; + stack_parameters : Boolean; + registerarea : PtrInt; begin - if target_info.abi=abi_xtensa_windowed then - list.Concat(taicpu.op_reg_const(A_ENTRY,NR_STACK_POINTER_REG,32)); + LocalSize:=align(LocalSize,4); + stack_parameters:=current_procinfo.procdef.stack_tainting_parameter(calleeside); + + { call instruction does not put anything on the stack } + registerarea:=0; + if not(nostackframe) then + begin + regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall); + a_reg_alloc(list,NR_STACK_POINTER_REG); + if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + Include(regs,RS_A15); + if pi_do_call in current_procinfo.flags then + Include(regs,RS_A0); + if regs<>[] then + begin + for r:=RS_A0 to RS_A15 do + if r in regs then + inc(registerarea,4); + end; + + inc(localsize,registerarea); + if LocalSize<>0 then + begin + localsize:=align(localsize,current_settings.alignment.localalignmax); + a_reg_alloc(list,NR_STACK_POINTER_REG); + list.concat(taicpu.op_reg_reg_const(A_ADDI,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,-localsize)); + end; + + reference_reset(ref,4,[]); + ref.base:=NR_STACK_POINTER_REG; + ref.offset:=localsize; + if ref.offset>1024 then + begin + if ref.offset<=1024+32512 then + begin + list.concat(taicpu.op_reg_reg_const(A_ADDMI,NR_A8,NR_STACK_POINTER_REG,ref.offset and $fffffc00)); + ref.offset:=ref.offset and $3ff; + ref.base:=NR_A8; + end + else + { fix me! } + Internalerror(2020031101); + end; + + if current_procinfo.framepointer<>NR_STACK_POINTER_REG then + begin + dec(ref.offset,4); + list.concat(taicpu.op_reg_ref(A_S32I,NR_A15,ref)); + a_reg_alloc(list,NR_FRAME_POINTER_REG); + list.concat(taicpu.op_reg_reg(A_MOV,NR_A15,NR_STACK_POINTER_REG)); + end; + + if regs<>[] then + begin + for r:=RS_A14 downto RS_A0 do + if r in regs then + begin + dec(ref.offset,4); + list.concat(taicpu.op_reg_ref(A_S32I,newreg(R_INTREGISTER,r,R_SUBWHOLE),ref)); + end; + end; + end; end; diff --git a/compiler/xtensa/xtensaatt.inc b/compiler/xtensa/xtensaatt.inc index e72b9afc0a..1ab042025b 100644 --- a/compiler/xtensa/xtensaatt.inc +++ b/compiler/xtensa/xtensaatt.inc @@ -2,6 +2,7 @@ 'none', 'add', 'addi', +'addmi', 'and', 'b', 'bt', diff --git a/compiler/xtensa/xtensaop.inc b/compiler/xtensa/xtensaop.inc index 0329524bcc..2cc02a95e7 100644 --- a/compiler/xtensa/xtensaop.inc +++ b/compiler/xtensa/xtensaop.inc @@ -2,6 +2,7 @@ A_NONE, A_ADD, A_ADDI, +A_ADDMI, A_AND, A_Bcc, A_BT,