Modeling 16-bit pointer registers for an 8-bit target

Pointer size on our target is 16-bits, and we have two 16-bit registers that can be used only to hold pointers (indirect addresses).

All operations on the target are 8-bit operations, so it takes two 8-bit loads to load these pointer registers.

We want LLVM to automatically expand all types to 8-bit values.

The problem is that LLVM does not expand GlobalAddresses, which are 16-bit values.

This in turn means that you have to specify a 16-bit register class, and once you specify a 16-bit register class, LLVM does not further expand 16-bit values.

Any suggestions on how to model this into LLVM?

TIA,

Sanjiv

Pointer size on our target is 16-bits, and we have two 16-bit registers that can be used only to hold pointers (indirect addresses).

All operations on the target are 8-bit operations, so it takes two 8-bit loads to load these pointer registers.

We want LLVM to automatically expand all types to 8-bit values.

The problem is that LLVM does not expand GlobalAddresses, which are 16-bit values.
This in turn means that you have to specify a 16-bit register class, and once you specify a 16-bit register class, LLVM does not further expand 16-bit values.

I don’t think there is code in Legalizer to expand GlobalAddress. But you can custom lower it. X86 custom lower GlobalAddress nodes for a different reason.

Evan

Legalize uses two primary predicates, isTypeLegal and isOperationLegal.
I guess your target tells Legalize that i16 as a legal type. The next step
is to tell legalize that loading a 16-bit GlobalAddress is not a legal
operation.

If you do that and it still doesn't work, it's a likely indication that
Legalize is making an assumption that isn't valid for your rather
unique architecture, and you should investigate correcting that assumption.

Dan

I don't think there is code in Legalizer to expand GlobalAddress. But

you

can custom lower it. X86 custom lower GlobalAddress nodes for a

different

reason.

Evan

Hmmm...That means we have to make i16 as a legal type (since
GlobalAddresses are 16-bits) and custom lower all 16-bit operations to
8-bit operations. I was thinking to take advantage of the already
present ExpandOp infrastructure.

-Sanjiv

You're likely to have much better luck with unusual stuff using the
LegalizeTypes infrastructure; pass -enable-legalize-types to llc to
enable it. It's not enabled yet because it still causes some
regressions, but the plan is to enable it at some point. With
LegalizeTypes, you can custom-legalize an operation in an illegal type
by just marking it custom and overriding ReplaceNodeResults in your
target; see X86TargetLowering::ExpandREADCYCLECOUNTER for an example.

-Eli

I don't think there is code in Legalizer to expand GlobalAddress. But

you

can custom lower it. X86 custom lower GlobalAddress nodes for a

different

reason.

Evan

Hmmm...That means we have to make i16 as a legal type (since
GlobalAddresses are 16-bits) and custom lower all 16-bit operations to
8-bit operations. I was thinking to take advantage of the already
present ExpandOp infrastructure.

You can, in a lot of cases. But not for GV's currently since the code isn't there. Most targets custom lower GV's currently.

Evan