On 02/06/2020 05:42, Sebastian Riedel wrote:
I don’t use stm8, but when I looked through it’s constraint functions, I saw that it allows things like notUsed('z')

And after a quick look into the OP codes, it looks like %1 and %2 could also be XH/YH/XL/YL/SP, which doesn’t seem to be supported by mov.

Ah, yes, I see there can be notUsed('n') and notUsed('z'); quite literally the first few rules in the STM8 peeph.def file use them - don't know how I didn't see!

The dst/src not being XL/XH/etc. is not really the only restriction that should be made - hence why I said I think the rule would need a restriction of %1 and %2 being only direct memory addresses (either 8-bit 'shortmem' or 16-bit 'longmem'). MOV only can be used in those two contexts (well, also immediate value to a memory location).

Perhaps it should be looked at the opposite way, and any LD instruction *not* involving X, Y, SP, an immediate value or indirect addressing in the operands is a candidate. How to do that? Maybe with notSimilar()? As far as I can see, it does substring matching within an operand, but I don't see any examples of its use in any peeph.def files of any platform, so I'm not sure. Maybe like this:

replace {
    ld a, %1
    ld %2, a
} by {
    mov %2, %1
} if notUsed('a'), notUsed('n'), notUsed('z'), notSimilar(%1  'x' 'y'  'sp'  '#'  '['  ']')

Will that work? Should it also have a "restart"?

On 02/06/2020 13:10, Philipp Klaus Krause wrote:
Compiling with --fverbose-asm (and sometimes --no-peep --i-code-in-asm)
often can help with such questions.

Also, for people on the list, it could help to see what CAN_PSR is (the
generated code might depend on use of __at vs. casting an integer into
an address).

Here is what was in the assembly listing when compiled with all those options:

;    can.c: 451: prev_page = CAN_PSR;
; ic:    44:     _can_rx_isr_prev_page_65537_99 [k33 lr0:0 so:0]{ ia1 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char auto} = @[0x5427 {volatile-unsigned-char generic* literal} + 0x0 {const-unsigned-char literal}]
; genPointerGet
    ld    a, 0x5427
    ld    _can_rx_isr_prev_page_65537_99+0, a

;    can.c: 513: CAN_PSR = prev_page;
; ic:    150:     *[0x5427 {volatile-unsigned-char generic* literal}] = _can_rx_isr_prev_page_65537_99 [k33 lr0:0 so:0]{ ia0 a2p0 re0 rm0 nos0 ru0 dp0}{unsigned-char auto}
; genPointerSet
    mov    0x5427+0, _can_rx_isr_prev_page_65537_99+0

The prev_page variable is declared as: static can_page_enum_t prev_page;

And can_page_enum_t is:

typedef enum {
    CAN_PG_TX_MBOX_0 = 0,
    // ...
    CAN_PG_RX_FIFO = 7
} can_page_enum_t;

CAN_PSR is defined as: #define CAN_PSR (*(volatile uint8_t *)(0x5427))

Regards,
Basil Hussain


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to