bug-mes
[Top][All Lists]
Advanced

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

Re: [bug-mes] mescc and Load/Store architectures


From: Jan Nieuwenhuizen
Subject: Re: [bug-mes] mescc and Load/Store architectures
Date: Thu, 07 Feb 2019 15:48:32 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux)

Danny Milosavljevic writes:

Hi Danny,

> most of the RISC architectures (ARM, MIPS and PowerPC) are a
> load/store architecture where the RAM is a distant slow peripheral
> which you need extra instructions to access (ARM: LDR to load from
> memory into register and STR to store from register to memory).

Ah, could that be where Stage0's preference for LOAD and STORE come
from, I wondered about that...

> Mes seems to assume CISC architecture at least partially and I'm
> having a hard time emulating all the CISC-specific instructions.

Yes, at least I recognize using the freely "mixing" aspect.

> Therefore, I wanted to ask whether it's possible to change the
> compiler not to use the most annoying instructions.

I think that makes sense.  I have tried to choose simplicity here
and have been wondering about these mixed instructions; I did not
have a clear direction until now.

> The most annoying instructions are:
>
> (1) MOV, ADD or CMP with one op immediate and one op memory.  It would
> be better to have only immediate -> register, register <-> memory
> transfers (as extra instructions).  Annoying example: add____$i8,0x32

> (2) PUSH from immediate directly to stack.  It would be better to have
> only immediate -> register, register <-> memory transfers (as extra
> instructions).  Annoying example: push___$i32

OK.

> Currently I implement (1) in arm.M1 via scratch registers whose value
> I save beforehand and restore afterwards.

I see.

> But (2) is really ugly because I have to push to the stack to save my
> scratch registers and then push to the stack to save the immediate -
> which is supposed to stay on.  Oops?

Hmm, indeed.

> Workarounds are possible, but easiest would be to get rid of the need
> to "save the scratch registers in arm.M1".  The best way to do that
> would be to move the decision which scratch registers to use into the
> compiler - it probably already does similar things anyway.
>
> What do you think?

Doing this right may seem more work right now than a workaround and will
involve changes to the intel backends too, but I think it's the right
thing to do.

It's nice for a proof of concept that this

> (1)
>
> # e92d0005        push    {r0, r2}
> # e5910000        ldr     r0, [r1]
> # e59f200c        ldr     r2, [pc, #12]   ; 1c <X2>
> # e0800002        add     r0, r0, r2
> # e5810000        str     r0, [r1]
> # e8bd0005        pop     {r0, r2}
> # ea000000        b       20 <Y2>
> # X2: data
> # Y2:
> DEFINE add____$i32,(%r1) 
> e92d0005e5910000e59f200ce0800002e5810000e8bd0005ea000000

"works" but let's try to avoid that.

It seems that an abstraction is missing or is just in the wrong place,
I don't see it very clearly just yet, so I'm open for any suggestions.

Maybe we can simply look at it case by case  e.g. looking at (2) PUSH immediate
to stack I think that's only used in one place: compile.scm:439 label->arg

For i386 we have

--8<---------------cut here---------------start------------->8---
(define (i386:label->arg info label i)
  `(("push___$i32" (#:address ,label))))
--8<---------------cut here---------------end--------------->8---

and currently that's exactly what we use for ARM.  What if we appoint
one scratch register 's' and do something like

--8<---------------cut here---------------start------------->8---
(define (armv4:label->arg info label i)
  `(("ldr____$i32,%s" (#:address ,label))
    ("push___%s)))
--8<---------------cut here---------------end--------------->8---

Would that be good enough for (2), or does the compiler need to know
about scratch register `s' and save it in certain cases?

Similar for armv4:r-mem-add, something like

--8<---------------cut here---------------start------------->8---
(define (armv4:r-mem-add info v)
  (let ((r (get-r info)))
    `(,(if (< (abs v) #x1000) `(,(string-append "ldr___(%" "r),%s")
                                ,(string-append "add___$i8,(%" s ")") 
(#:immediate1 ,v)
                                ,(string-append "str___%s,(" r ")"))
           `(,(string-append "ldr___(%" "r),%s")
             ,(string-append "add____$i32,(%" r ")") (#:immediate ,v)
             ,(string-append "str___%s,(" r ")"))))))
--8<---------------cut here---------------end--------------->8---

...(and possibly the ldr and str in both THEN and ELSE branches can be
shared, etc.)

Even if this works it could still be a better idea to pull it further
into the compiler (compile.scm) where these are used...I'm not sure.
WDYT?

Greetings,
janneke

-- 
Jan Nieuwenhuizen <address@hidden> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | AvatarĀ® http://AvatarAcademy.com



reply via email to

[Prev in Thread] Current Thread [Next in Thread]