Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane

From: Dylan McKay <dylanmckay34 <at> gmail.com>
Subject: Encoding instructions with inconsistent formats
Newsgroups: gmane.comp.compilers.llvm.devel
Date: Saturday 31st January 2015 08:40:39 UTC (over 3 years ago)
I'm attempting to implement codegen support for the AVR ST/LD
<http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_ST.html>
family
of instructions.

The binary encoding is not particularly consistent -- take a look at this
table of variants of LD, along with their machine code representation:

# load 8 bits from pointer register X into general purpose Rd

ld Rd, X    `1001 000d dddd 1100`
ld Rd, X+   `1001 000d dddd 1101` (load with postincrement)
ld Rd, -X   `1001 000d dddd 1110` (load with predecrement)

ld Rd, Y    `1000 000d dddd 1000`
ld Rd, Y+   `1001 000d dddd 1001`
ld Rd, -Y   `1001 000d dddd 1010`

ld Rd, Z    `1000 000d dddd 0000`
ld Rd, Z+   `1001 000d dddd 0001`
ld Rd, -Z   `1001 000d dddd 0010`
                ^
                |
             Note this one inconsistent bit

One way to solve this solution would be to to describe them in InstrInfo.td
as seperate instructions. Note that R27R26 is a pointer register defined in
AVRRegisterInfo.td, and 'X' is an alias for this.

let Uses = [R27R26],
canFoldAsLoad = 1,
isReMaterializable = 1 in
def LDRdX :   FSTLDPtrReg<0b0,
                          (outs GPR8:$reg),
                          (ins),
                          "ld\t$reg, X",
                          [(set GPR8:$reg, (load R27R26))]>;

def LDRdY : FSTLDPtrReg<0b0,

// ...

 When I do this, however, I get errors that the pointer register is an
invalid operand type.

Another solution might be to have a generic 'LD' pseudo instruction, which
is later lowered into one of the 9 variants, which each have the correct
encoding. This is a messy, hacky solution, which also bloats the code a
fair bit more.

One last solution is to 'make up a pattern' for the inconsistent bit that
fits.
It is:

Inconsistent bit = (postinc OR predec) OR IsPtrXReg

Where 'postinc' and 'predec' is 1 if the respective mode is used, and 0
otherwise, and IsPtrXReg is 1 if the pointer register is X.

I have tried to assign this bit using this expression with macros in
AVRInstrInfo.td, but I couldn't get it to compile (!or is not defined, and
I don't think macros will solve this situation regardless).
 
CD: 14ms