|
@@ -158,6 +158,7 @@ uses
|
|
|
type
|
|
|
taicpu = class(tai_cpu_abstract_sym)
|
|
|
oppostfix : TOpPostfix;
|
|
|
+ wideformat : boolean;
|
|
|
roundingmode : troundingmode;
|
|
|
procedure loadshifterop(opidx:longint;const so:tshifterop);
|
|
|
procedure loadregset(opidx:longint; regsetregtype: tregistertype; regsetsubregtype: tsubregister; const s:tcpuregisterset);
|
|
@@ -246,8 +247,9 @@ uses
|
|
|
function setroundingmode(i : taicpu;rm : troundingmode) : taicpu;
|
|
|
function setcondition(i : taicpu;c : tasmcond) : taicpu;
|
|
|
|
|
|
- { inserts pc relative symbols at places where they are reachable }
|
|
|
- procedure insertpcrelativedata(list,listtoinsert : TAsmList);
|
|
|
+ { inserts pc relative symbols at places where they are reachable
|
|
|
+ and transforms special instructions to valid instruction encodings }
|
|
|
+ procedure finalizearmcode(list,listtoinsert : TAsmList);
|
|
|
{ inserts .pdata section and dummy function prolog needed for arm-wince exception handling }
|
|
|
procedure InsertPData;
|
|
|
|
|
@@ -958,6 +960,74 @@ implementation
|
|
|
curdata.free;
|
|
|
end;
|
|
|
|
|
|
+
|
|
|
+ procedure ensurethumb2encodings(list: TAsmList);
|
|
|
+ var
|
|
|
+ curtai: tai;
|
|
|
+ op2reg: TRegister;
|
|
|
+ begin
|
|
|
+ { Do Thumb-2 16bit -> 32bit transformations }
|
|
|
+ curtai:=tai(list.first);
|
|
|
+ while assigned(curtai) do
|
|
|
+ begin
|
|
|
+ case curtai.typ of
|
|
|
+ ait_instruction:
|
|
|
+ begin
|
|
|
+ case taicpu(curtai).opcode of
|
|
|
+ A_ADD:
|
|
|
+ begin
|
|
|
+ { Set wide flag for ADD Rd,Rn,Rm where registers are over R7(high register set) }
|
|
|
+ if taicpu(curtai).ops = 3 then
|
|
|
+ begin
|
|
|
+ if taicpu(curtai).oper[2]^.typ in [top_reg,top_shifterop] then
|
|
|
+ begin
|
|
|
+ if taicpu(curtai).oper[2]^.typ = top_reg then
|
|
|
+ op2reg := taicpu(curtai).oper[2]^.reg
|
|
|
+ else if taicpu(curtai).oper[2]^.shifterop^.rs <> NR_NO then
|
|
|
+ op2reg := taicpu(curtai).oper[2]^.shifterop^.rs
|
|
|
+ else
|
|
|
+ op2reg := NR_NO;
|
|
|
+
|
|
|
+ if op2reg <> NR_NO then
|
|
|
+ begin
|
|
|
+ if (taicpu(curtai).oper[0]^.reg >= NR_R8) or
|
|
|
+ (taicpu(curtai).oper[1]^.reg >= NR_R8) or
|
|
|
+ (op2reg >= NR_R8) then
|
|
|
+ begin
|
|
|
+ taicpu(curtai).wideformat:=true;
|
|
|
+
|
|
|
+ { Handle special cases where register rules are violated by optimizer/user }
|
|
|
+ { if d == 13 || (d == 15 && S == ‘0’) || n == 15 || m IN [13,15] then UNPREDICTABLE; }
|
|
|
+
|
|
|
+ { Transform ADD.W Rx, Ry, R13 into ADD.W Rx, R13, Ry }
|
|
|
+ if (op2reg = NR_R13) and (taicpu(curtai).oper[2]^.typ = top_reg) then
|
|
|
+ begin
|
|
|
+ taicpu(curtai).oper[2]^.reg := taicpu(curtai).oper[1]^.reg;
|
|
|
+ taicpu(curtai).oper[1]^.reg := op2reg;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ curtai:=tai(curtai.Next);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+ procedure finalizearmcode(list, listtoinsert: TAsmList);
|
|
|
+ begin
|
|
|
+ insertpcrelativedata(list, listtoinsert);
|
|
|
+
|
|
|
+ { Do Thumb-2 16bit -> 32bit transformations }
|
|
|
+ if current_settings.cputype in cpu_thumb2 then
|
|
|
+ ensurethumb2encodings(list);
|
|
|
+ end;
|
|
|
+
|
|
|
procedure InsertPData;
|
|
|
var
|
|
|
prolog: TAsmList;
|