[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [MiNT] Pexec() patch in FireTOS



Hi Lonny,

I think nobody can tell if this patch will make it work, but at least it will take you a good deal forward.

The background is that the Pure C libs use a feature/quirk in the 68k architecture to speed up the code a bit.

They avoid a slow (on 68000 only) lsl.w #8,xxx (a multiplication by 256) by pushing a byte to the stack and fetching it back as a word.

The m68k requires a word-aligned stack. Motorola engineers decided to implement a 'self healing stack' feature that silently extends a byte pushed to the stack into a word to keep the alignment. Which I found always ugly btw, since it makes the - otherwise pretty and straightforward - instruction set unorthogonal, making the A7 register behave differently than any other address register - in my opinion it should just crash in such case.

(Ab-)using that feature, you can pop this extended byte back as a word, effectively resulting in a left shift by 8 bits. On mc68000 that lacks the barrel shifter later chips had (which made shift execution times independend of shift size), this is much faster than the equivalent (clean and slow) lsl.w instruction.

Coldfires can deal with an unaligned stack (it just makes them a little slower), so Freescale removed that 'self healing stack' feature from the instruction set. If you push a byte and pop a word on Coldfires, you get the low byte of whatever was on the next higher stack address in the high byte of the popped word, but even worse, you damage the next higher stack contents resulting in a crash sooner or later.

Bad decisions always get punished. It just takes a while, sometimes

Cheers,
Markus

P.S.: this is something the cf68klib (the m68k emulation library used in FireTOS) cannot catch and fix on the fly as it does for other incompatible m68k code. The cf68klib relies on exceptions fired by incompatible instructions. As the instruction stream of Pure C's memset() implementation is perfectly valid code on Coldfire as well (it just yields different results), there is no exception to catch. Thus, FireTOS intercepts Pexec() and explicitly scans for the specific byte pattern of Pure C's memset() library routine to apply a patch. This fixes the issue for Pure C compiled programs, but other code (that has a different byte pattern but also uses this 'trick') will still fail.

Am 26.08.2015 um 02:32 schrieb Lonny Pursell:
I was looking at this:
http://www.atariforge.org/gf/project/ctpci/scmsvn/?action=browse&path=%2Fbra
nches%2F1.04-pm%2Fflash.tos%2Ftos%2Fgemdos2.S&revision=6&view=markup

After some study I see that this patch is searching for the code that makes
up memset() in the PureC library. Inside the LDG library is a call to
memset() which in turn makes all of codecs built against the LDG library
fail on the firebee. So is is enough to replace the memset() call with a
patch one to get my codecs working on the firebee?