that the type of the parameters can be determined automatically
o added compilerproc declarations for all helpers called in the compiler
via their assembler name, so we can look up the corresponding procdef
git-svn-id: trunk@23325 -
Add simple Mul+Sub/Mul+Add into MLS/MLA optimizations
Fix some other small issues in the optimizer
Implement Interlocked* functions with proper use of LDREX/STREX
git-svn-id: branches/laksen/arm-embedded@22801 -
Especially with 64bit operators the CG sometimes generates:
and r0, r1, #0
Which just clears r0 and is equivalent with
mov r0, #0
git-svn-id: trunk@22032 -
In certain cases the CG would emit something like
bic r1, r0, #0
As BIC is clearing the specified bits this is equivalent to
mov r1, r0
This patch changes the CG to emit the mov instead which the register
allocator will hopefully remove most of the time.
git-svn-id: trunk@22024 -
The old code generated a strange IT-sequence:
IT EQ
MOVEQ r0, #1
IT NE
MOVNE r0, #1
Now we generate:
ITE EQ
MOVEQ r0, #1
MOVNE r0, #1
IT stands for IfThen, ITE for IfThenElse it has a couple of other forms
where the instruction gets extended to handle more of the following
instructions. So we have ITEE, ITETE etc, up to 4 instructions can be
handled.
git-svn-id: trunk@21996 -
If the needed adjustment is not expressible in a shifterconst, the old code
loaded a temporary register (fixed to r12) via a_load_const_reg and used it
to adjust the SP. Resulting in:
mov r12, #44
orr r12, r12, #4096
sub sp, sp, r12
The new code will try to split the adjustment into 2 shifterconstants and
will do two seperate adjustments:
sub sp, sp, #44
sub sp, sp, #4096
If that doesn't work we'll fall back to the old code. But that should
happen VERY rarely, only for stacks bigger than 256k which are not
expressible in 2 shifter constants.
git-svn-id: trunk@21863 -
This removes the duplications in a_op_reg_reg_reg_checkoverflow.
OP_ROL stays seperate because it needs some special treatment again.
The code for OP_ROL was changed, previously it generated:
mov tempreg, #32
sub src1, tempreg, src1
mov dst, src2, ror src1
This would trash src1, which MIGHT be a problem, but i'm not totally
sure. But the mov/sub was replaced with rsb, so the new code looks like
this.
rsb tempreg, src1, #32
mov dst, src2, ror tempreg
If src1 gets freed afterwards the regallocator should be able to change
that into:
rsb src1, src1, #32
mov dst, src2, ror src1
git-svn-id: trunk@21804 -
The previous code was full with duplicated code, this new version just
maps the OP_* to the correct SM_* and does some special handling for
OP_ROL which is done via OP_ROR.
git-svn-id: trunk@21801 -
getintparaloc + adapted all call sites of getintparaloc. This
led to a number of additional, related changes:
o corrected the type information for some getintparaloc parameters
o don't allocate some intparalocs in cases they aren't used
o changed "const tvardata" parameter into "constref tvardata" for
fpc_variant_copy_overwrite to make pass-by-reference semantics
explicit
o moved a number of routines that now have to call find_system_type()
from cgobj to hlcgobj so that cgobj doesn't have to start depending
on the symtable unit
o added versions of the cpureg alloc/dealloc methods to hlcgobj that
call through to their cgobj counter parts, so we can call save/restore
the cpu registers before/after calling system helpers from hlcgobj
(not implemented in hlcgobj itself, because all basic register
allocator functionality is still part of cgobj/cgcpu)
git-svn-id: trunk@21696 -
This now generates:
mvn r0, r0, lsl #24/#16
mov r0, r0, lsr/asr #24/#16
The lsr/asr might be folded into a following instruction, making the
whole operation 1 cycle instead of 2-3 with the previous solution.
git-svn-id: trunk@21658 -
OP_ADD, OP_SUB, OP_ORR will be split into two intructions if possible when a load/const
construction is required.
OP_AND is a bit different, because we can't just split it up, but we try
to find a two instruction BIC-equivalent to it.
Till now code like
a:= a and $FFFF;
produced code like
mov r0, $FF00
orr r0, r0, $FF
and r1, r1, r0
With this addition we produce code like:
bic r0, r0, $FF00
bic r0, r0, $FF
Saving us at least a cycle and in some cases also a load from the
constant-pool.
This uses the new split_into_shifter_const function.
git-svn-id: trunk@21647 -
* use split_into_shifter_const to reduce the MOV/ORR combination to a
single check and allow a broader rang of combinations.
* Introduce MVN/BIC combination to load values which have more 1 than 0
bits set (like small negative values)
git-svn-id: trunk@21646 -
BIC clears the specified bits, while AND keeps them. The usage of BIC
allows a broader range of shifterconsts to be used on the ARM cpu, often
saving a cycle.
Previously code like:
Data:=Data and $FFFFFF00
would result in
mvn r1, #255
and r0, r0, r1
This patch changes this to
bic r0, r0, #255
git-svn-id: trunk@21510 -
BX is supported from ARMv4T onwards, but i don't have a armv4t device to
test it.
Using BX instead of mov pc,lr allows for a better pipeline utilization
by enabling the CPUs branch predictor to work properly.
git-svn-id: trunk@21505 -
Reorder unaligned Load sequence on ARM
The old version produced code like that:
ldrb rDEST, [rBASE]
ldrb rTemp, [rBASE, #1]
orr rDEST, rDEST, rTEMP lsl #8 (2 stall cycles)
ldrb rTemp, [rBASE, #2]
orr rDEST, rDEST, rTEMP lsl #16 (2 stall cycles)
ldrb rTemp, [rBASE, #3]
orr rDEST, rDEST, rTEMP lsl #24 (2 stall cycles)
This creates a lot of stall-cycles on ARM Implementations with load
delay slots like Marvel Kirkwood or Intel XScale. With the usual up to 2
stall-cycles this code requires a total of 13 cycles (7 instructions + 6 stall
cycles) in best case.
The new code uses a second temp register to avoid the stall cycles.
ldrb rDEST, [rBASE]
ldrb rTemp1, [rBASE, #1]
ldrb rTemp2, [rBASE, #2]
orr rDEST, rDEST, rTEMP1 lsl #8
ldrb rTemp1, [rBASE, #3]
orr rDEST, rDEST, rTEMP2 lsl #16
orr rDEST, rDEST, rTEMP1 lsl #24 (1 stall cycle)
The rescheduling and second register bring the total cycles down to 8.
If a later rescheduling should happen for the last orr it even can go
down to 7.
git-svn-id: trunk@21363 -
Optimize ARM OP_MUL/OP_IMUL for x*ispowerof2(const+1) cases
Calculations like a*7 can be optimized to a*8-a with the usage of RSB and left
shifts which can be done in a single cycle.
git-svn-id: trunk@21351 -
always points to the previous r7 on the stack (with the saved return
address coming right after it) so that the debugger and crashreporter
can use it for backtraces as specified in the ABI
o changed NR_FRAME_POINTER_REG and RS_FRAME_POINTER_REG from a symbolic
into a typed constant, and added a new method to tprocinfo that can
be used to initialze it (so it can be inited to r7/r11 depending on
the target platform)
* allow using r9 on Darwin, it was only used by the system on iOS up to
2.x, which we no longer support
* prefer using r9 and r12 before r4..r11 on Darwin, because they are
volatile and hence do not have to be saved
git-svn-id: trunk@20661 -
o new eabihf (hard float) abi
o vfpv3_d16 variant of VFP (default variant used by EABI assemblers: VFPv3
with only 16 double registers instead of 32) and pass it to GNU as
o make the odd numbered single precision floating point VFP registers
available for explicit allocation for use by the calling convention
* fixed copy/paste error in stdname of S30 register
-> use -dFPC_ARMHF to create an ARM eabi hard float compiler
(mantis #21554)
git-svn-id: trunk@20660 -