how to declare that two registers must be different

The ARM has a multiply instruction of the form
Rd=Rm*Rs

where Rd != Rm. How can I add this requirement to the instruction definition?

Thanks,
Rafael

Unfortunately there is currently no great way to do this. Some options are:

1. Pin one operand to a specific register, one that isn't allocated (e.g.
    R12). Use copyto/fromreg to get to it. They other would be allocated
    to some different reg.
2. Allocate like normal, and then do a post-pass. The post-pass would
    scan for the bad instruction, and if found insert compensation code to
    copy in/out of some other reg (again, R12 would a natural choice).

I'd like to make the regalloc interfaces more powerful to be able to capture this sort of thing, but I'm not very familiar with ARM. What specific instructions are problematic? MUL looks ok in my copy of the ARM ARM.

-Chris

Hi Chris,

> The ARM has a multiply instruction of the form Rd=Rm*Rs where Rd !=
> Rm. How can I add this requirement to the instruction definition?

...

I'd like to make the regalloc interfaces more powerful to be able to
capture this sort of thing, but I'm not very familiar with ARM. What
specific instructions are problematic? MUL looks ok in my copy of the
ARM ARM.

MUL (and MLA, MuLtiply and Accumulate) are the two well known ones. The
very unofficial, but historically good,
http://www.pinknoise.demon.co.uk/ARMinstrs/ARMinstrs.html#Multiplication
says

    "The destination register shall not be the same as the operand
    register Rm. R15 shall not be used as an operand or as the
    destination register."

Then there's the long multiplication instruction on some ARM
architectures,

    (U|S)(MUL|MLA)L Rl, Rh, Rm, Rs

which calculate Rm * Rs and overwrite or accumulate the 64-bit result
into Rl and Rh. pinknoise says

    "The program counter, R15 should not be used. Rh, Rl and Rm should
    be different."

which allows Rs to be the same as one of the other three.

Then, for the load and store multiple instructions, LDM and STM, the R15
should not be used as the base register. Neither should R15 be the
destination for an MCR, Move to Co-processor register from Register.

These are some examples, hopefully enough to alter the regalloc
interface to cope.

Cheers,

Ralph.

    "The destination register shall not be the same as the operand
    register Rm. R15 shall not be used as an operand or as the
    destination register."

The ARM ARM has this "Operand restriction" on MUL:
Specifying the same register for <Rd> and <Rm> has UNPEDICTABLE results.

Then, for the load and store multiple instructions, LDM and STM, the R15
should not be used as the base register. Neither should R15 be the
destination for an MCR, Move to Co-processor register from Register.

These are some examples, hopefully enough to alter the regalloc
interface to cope.

Restrictions of the form cannot be register Rx can be solved by
creating a register class without Rx. The problem is the "must not be
the same" restriction.

Cheers,

Ralph.

Thanks,
Rafael

Rafael Espíndola wrote:

    "The destination register shall not be the same as the operand
    register Rm. R15 shall not be used as an operand or as the
    destination register."

The ARM ARM has this "Operand restriction" on MUL:
Specifying the same register for <Rd> and <Rm> has UNPEDICTABLE results.

Then, for the load and store multiple instructions, LDM and STM, the R15
should not be used as the base register. Neither should R15 be the
destination for an MCR, Move to Co-processor register from Register.

These are some examples, hopefully enough to alter the regalloc
interface to cope.

Restrictions of the form cannot be register Rx can be solved by
creating a register class without Rx. The problem is the "must not be
the same" restriction.

Is it allowed now to have overlapping register classes? It was not allowed
last time I tried (admittedly long ago).

- Volodya

    "The destination register shall not be the same as the operand
    register Rm. R15 shall not be used as an operand or as the
    destination register."

The ARM ARM has this "Operand restriction" on MUL:
Specifying the same register for <Rd> and <Rm> has UNPEDICTABLE results.

My copy of the ARM ARM says:

"Use of R15: Specifying R15 for register <Rd>, <Rm>, or <Rs> has UNPREDICTABLE results."

This is the same as above. However, it goes on to say:

"Operand restriction: Specifying the same register for <Rd> and <Rm> was previously described as producing UNPREDICTABLE results. There is no restriction in ARMv6, and it is believed all relevant ARMv4 and ARMv5 implementations do not require this restriction either, because high performance multipliers read all their operands prior to writing back any results."

Perhaps this isn't an issue any more? I don't know the arch well enough to know what it means by "all relevant" implementations.

-Chris

Then, for the load and store multiple instructions, LDM and STM, the R15
should not be used as the base register. Neither should R15 be the
destination for an MCR, Move to Co-processor register from Register.

These are some examples, hopefully enough to alter the regalloc
interface to cope.

Restrictions of the form cannot be register Rx can be solved by
creating a register class without Rx. The problem is the "must not be
the same" restriction.

Cheers,

Ralph.

Thanks,
Rafael
_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris

Ok, this is easy enough to handle. IIUC, R15 is the PC, which isn't allocatable.

-Chris

They are allowed, but don't work particularly well. It's also on the todo list. :slight_smile:

- Volodya

My copy of the ARM ARM says:

"Use of R15: Specifying R15 for register <Rd>, <Rm>, or <Rs> has
UNPREDICTABLE results."

This is the same as above. However, it goes on to say:

"Operand restriction: Specifying the same register for <Rd> and <Rm> was
previously described as producing UNPREDICTABLE results. There is no
restriction in ARMv6, and it is believed all relevant ARMv4 and ARMv5
implementations do not require this restriction either, because high
performance multipliers read all their operands prior to writing back any
results."

Perhaps this isn't an issue any more? I don't know the arch well enough
to know what it means by "all relevant" implementations.

I think that I will ask for a new ARM ARM :slight_smile:

The gnu assemble gives an error if rd and rm are the same. Even with
-march=armv6. So I think that I will have to implement an workaround
anyway.

-Chris

Thank you very much,
Rafael

Hi

Rafael wrote:

Chris Lattner wrote:
> Perhaps this isn't an issue any more? I don't know the arch well
> enough to know what it means by "all relevant" implementations.

I think that I will ask for a new ARM ARM :slight_smile:

The gnu assemble gives an error if rd and rm are the same. Even with
-march=armv6. So I think that I will have to implement an workaround
anyway.

And it would be nice to be able to add support for those older
architectures someday.

Cheers,

Ralph.