The new relocation type RELOLIS handles these instructions:
lis RT, ha16[expr] == addis RT, r0, ha16[expr]
lis RT, hi16[expr] == addis RT, r0, hi16[expr]
RELOLIS stores a 32-bit value in the program text. In this value, the
high bit is a ha16 flag, the next 5 bits are the target register RT,
and the low bits are a signed 26-bit offset. The linker replaces this
value with the lis instruction.
The old RELOPPC relocated a ha16/lo16 or hi16/lo16 pair. The new
RELOLIS relocates only a ha16 or hi16, so it is no longer necessary to
have a matching lo16 in the next instruction. The disadvantage is
that RELOLIS has only a signed 26-bit offset, not a 32-bit offset.
Switch the assembler to use RELOLIS for ha16 or hi16 and RELO2 for
lo16. The li32 instruction still uses the old RELOPPC relocation.
This is not the same as my RELOPPC change from my recent mail to
tack-devel (https://sourceforge.net/p/tack/mailman/message/35651528/).
This commit is on a different branch. Here I am throwing away my
RELOPPC change and instead trying RELOLIS.
We should not include a system header file here, because
mach/proto/as/comm2.y goes through cpp twice. The include can cause
problems like https://github.com/davidgiven/ack/issues/1
Remove this include #<stdbool.h> and leave a comment pointing to the
includes in comm0.h. Change the few instances of bool, false, true,
to int, 0, 1.
Type word_t is for encoding the machine instructions. It only needs
32 bits for PowerPC. It was long (which can have 32 or 64 bits), and
there was a second type quad (which was uint32_t). Switch word_t to
uint32_t and replace quad with word_t.
Also change valu_t and ADDR_T away from long.
They must use OP_RA_RS_RB_C instead of OP_RS_RA_RB_C. The code
generator often sets RS and RA to the same register, so swapping them
causes no change in many programs.
I also rename OP_RS_RA_UI_CC to OP_RA_RS_UI_CC, and OP_RS_RA_C to
OP_RA_RS_C, because they already swap RA and RS.
Also make a few changes to basic mnemonics. Fix typo in name of the
basic "creqv". Add the basic "addc" and relatives, because it would
be odd to have the extended "subc" without "addc". Fix the basic
"rldicl", "rldicr", "rldic", "rldimi" to correctly encode the 6-bit MB
field. Fix "slw" and relatives to correctly swap their RA and RS
operands.
Add many, but not all, of the extended mnemonics from IBM's Power ISA
Version 2.06 Book I Appendix E. (I used 2.06, published 2009, just
because I already had the PDF of it.) This commit includes mnemonics
for branching, subtraction, traps, bit rotation, and a few others,
like "mflr" and "nop". The assembler now understands branches like
`beq cr7, label` and bit shifts like `slwi r7, r7, 2`. These encode
the same machine instructions as the basic "bc" and "rlwinm".
Some operands to basic names become optional. The assembler no longer
requires the level in "sc" or the branch hint in "bcctr" and "bclr";
they default to zero. Some extended names take an optional branch
hint or condition register.
Some extended names are still missing. I don't provide names with
static branch prediction, like "beq+" or "bge-", because the assembler
parses '+' and '-' as operators, not as part of an instruction name.
I also don't provide some names that 2.06 has for moving to or from
the condition register or some special purpose registers, names like
"mtcr" or "mfuamr".
This commit also deletes some unused tokens and one unused yacc rule.
assembler directives, ha16() and has16(), for the upper half; has16() applies
the sign adjustment. .powerpcfixup is now gone, as we generate the relocation
in ha*() instead. Add special logic to the linker for undoing and redoing the
sign adjustment when reading/writing fixups. Tests still pass.
PowerPC has a few hundred special-purpose registers. The assembler
had only accepted the names "xer", "lr", "ctr". Most programs use
only those three SPRs. If I add more names, they would almost never
get used, and they might conflict with labels.
I want to use "mfspr r3, 0x3f0" and "mtspr 0x3f0, r3" in
plat/qemu/boot.s to access register hid0 from supervisor mode.
GNU as has "la %r4,8(%r3)" as an alias for "addi %r4,%r3,8", meaning
to load the address of the thing at 8(%r3). Our 'la', now 'li32',
makes an addis/ori pair to load an immediate 32-bit value. For
example, "li32 r4,23456789" loads a big number.
calculated incorrectly because of overflow errors.
Replace it with an extended RELOPPC relocation which understands addis/ori
pairs; add an la pseudoop to the assembler which generates these and the
appropriate relocation. Make good.
--HG--
branch : dtrg-experimental-powerpc-branch