Commit graph

133 commits

Author SHA1 Message Date
George Koehler 73ad5a227d Rename RELOLIS to RELOPPC_LIS.
This relocation is specific to PowerPC.  @davidgiven suggested the
name RELOPPC_LIS in
https://github.com/davidgiven/ack/pull/52#issuecomment-279856501

Reindent the list in h/out.h and util/led/ack.out.5 because
RELOLIS_PPC is a long name.  I use spaces and no tabs because the tabs
looked bad in the manual page.
2017-10-18 15:39:31 -04:00
George Koehler 459a9b5949 Use lwzu, stwu to tighten more loops.
Because lwzu or stwu moves the pointer, I can remove an addi
instruction from the loop, so the loop is slightly faster.

I wrote a benchmark in Modula-2 that exercises some of these loops.  I
measured its time on my old PowerPC Mac.  Its user time decreases from
8.401s to 8.217s with the tighter loops.
2017-10-18 12:12:42 -04:00
George Koehler ac2b0710c8 Add more rules for single-precision reg_float.
The result of single-precision fadds, fsubs, and such can go into a
register variable, like we already do with double precision.  This
avoids an extra fmr from a temporary register to the regvar.
2017-10-17 17:53:03 -04:00
George Koehler 47bd0ef7a7 Stop inlining code to convert integers to floats.
Do the conversion by calling .cif8 or .cuf8 in libem, as it was done
before my commit 1de1e8f.  I used the inline conversion to experiment
with the register allocator, which was too slow until c5bb3be.

Now that libem has the only copy of the code, move some comments and
code changes there.
2017-10-17 17:00:28 -04:00
George Koehler 893e170015 Use my new regvar_w() and regvar_d() in PowerPC ncg.
Rename GPRE to GPR_EXPR, then define FPR_EXPR and FSREG_EXPR.  Use
them for moves to register variables.

Keep "kills regvar($1)", because deleting it and recompiling libc
would cause many failures in my test programs.  Add comment to warn,
  /* ncg fails to infer that regvar($1) is dead! */

Remove "kills LOCAL %off==$1" because it seems to have no effect.
2017-10-17 14:15:33 -04:00
George Koehler 5432bd03d6 Do a move when coercing FREG to FREG or FSREG to FSREG. 2017-10-16 12:07:55 -04:00
George Koehler f0619ea4ae PowerPC ncg never uses the rules to stack LOCAL or DLOCAL. 2017-10-15 15:22:52 -04:00
George Koehler 7e9348169c Add reglap to ncg. Add 4-byte reg_float to PowerPC ncg.
The new feature "reglap" allows two sizes of floating-point register
variables (reg_float), if each register overlaps a single register of
the other size.  PowerPC ncg uses reglap to define 4-byte instances
of f14 to f31 that overlap the 8-byte instances.

When ncgg sees the definition of fs14("f14")=f14, it removes the
8-byte f14 from its rvnumbers array, and adds the 4-byte fs14 in its
place.  Later, when ncg puts a variable in fs14, if it is an 8-byte
variable, then ncg switches to the 8-byte f14.  The code has
/* reglap */ comments in util/ncgg or #ifdef REGLAP in mach/proto/ncg

reglap became necessary because my commit a20b87c caused PowerPC ego
to allocate reg_float in both 4-byte and 8-byte sizes.
2017-10-14 12:40:04 -04:00
George Koehler 2c266c631a Reorder registers. Fix problem with ret 8.
After c5bb3be, ncg began to allocate regvars from r13 up.  I reorder
the regvars so ncg again allocates them from r31 down.  I also reorder
the other registers.

This exposed a bug in my rule for ret 8.  It was wrong if item %2 was
in r3, because I moved %1 to r3 before %2 to r4.  Fix it by adding
back an individual register class for r3 (called REG3 here, GPR3 in
c5bb3be).

Also fix my typo in mach.c that made a syntax error in assembly.
2017-02-17 19:32:27 -05:00
George Koehler 23c365c939 Fix comparison of 4-byte floats.
I broke it in f64b7d8.  My stack pattern had the wrong type of
registers.  The comparison popped too many bytes and corrupted the
stack.
2017-02-17 19:29:45 -05:00
George Koehler 736c45453c Remove .ret from libem and inline the code.
This removes a wrong-way dependency of libsys on libem.  The C
functions in libsys called .ret, but libsys is after libem in the
linker arguments, so the linker didn't find .ret unless something else
had called .ret.  Almost everything called .ret, but I got a linker
error when I wrote an assembly program using the EM runtime, because
my assembly program didn't call .ret.

Add a dummy comment to build.lua, so git checkout touches that file,
the build system reconfigures itself, and the *.s glob sees that ret.s
has gone.
2017-02-16 21:18:39 -05:00
George Koehler e6df553ebf For PowerPC, never put a reg_float value in a reg_any.
With this type check, I can change the size checks into assertions.
2017-02-16 20:30:17 -05:00
George Koehler cbe5d8640b Add floating-point register variables to PowerPC ncg.
Use f14 to f31 as register variables for 8-byte double-precison.
There are no regvars for 4-byte double precision, because all
regvar(reg_float) must have the same size.  I expect more programs to
prefer 8-byte double precision.

Teach mach/powerpc/ncg/mach.c to emit stfd and lfd instructions to
save and restore 8-byte regvars.  Delay emitting the function prolog
until f_regsave(), so we can use one addi to make stack space for both
local vars and saved registers.  Be more careful with types in mach.c;
don't assume that int and long and full are the same.

In ncg table, add f14 to f31 as register variables, and some rules to
use them.  Add rules to put the result of fadd, fsub, fmul, fdiv, fneg
in a regvar.  Without such rules, the result would go in a scratch
FREG, and we would need fmr to move it to the regvar.  Also add a rule
for pat sdl inreg($1)==reg_float with STACK, so we can unstack the
value directly into the regvar, again without a scratch FREG and fmr.

Edit util/ego/descr/powerpc.descr to tell ego about the new float
regvars.  This might not be working right; ego usually decides against
using any float regvars, so ack -O1 (not running ego) uses the
regvars, but ack -O4 (running ego) doesn't use the regvars.

Beware that ack -mosxppc runs ego using powerpc.descr but -mlinuxppc
and -mqemuppc run ego without a config file (since 8ef7c31).  I am
testing powerpc.descr with a local edit to plat/linuxppc/descr to run
ego with powerpc.descr there, but I did not commit my local edit.
2017-02-15 19:34:07 -05:00
George Koehler cf728c2a2a Implement lxl for PowerPC ncg.
This fixes lxl 1 (so it follows the static chain, not the dynamic
chain) and provides lxl 2 and greater.  The Modula-2 compiler uses lxl
for nested procedures, so they can access the variables of the
enclosing procedures.
2017-02-13 23:22:31 -05:00
George Koehler a8f62f44d8 Remove REG_PAIR.
I added REG_PAIR in cfbc537 to speed up the register allocator,
because ncg was taking about 2 seconds on each sti 8.  I defined only
4 such pairs, so allocating REG_PAIR was much faster than allocating
REG REG.

After my last commit c5bb3be, allocation of REG REG is fast, and
REG_PAIR seems unnecessary.
2017-02-13 18:11:27 -05:00
George Koehler c5bb3be495 Speed up register allocation by removing some register classes.
The table for PowerPC had placed each GPR and FPR into an individual
register class (like GPR3, GPR4, FPR1, FPR2), and had used these
classes to coerce stack values into specific registers.  But ncg does
not like having many register classes.

In http://tack.sourceforge.net/olddocs/ncg.pdf
Hans van Staveren wrote:

> Every extra property means the register set is more unorthogonal and
> *cg* execution time is influenced by that, because it has to take
> into account a larger set of registers that are not equivalent.  So
> try to keep the number of different register classes to a minimum.

Recent changes to the PowerPC table have removed many coercions to
specific registers.  Many functions in libem switched from taking
values in registers to taking them from the stack (see dc05cb2).

I now remove all 64 individual register classes of GPR and FPR.  In
the few cases where I need a stack value in a specific register, I now
do a move (as the arm and m68020 tables do).

This commit speeds the compilation of some files.  For my test file
fconv.c, the compilation time goes from over 20 seconds to under 1
second.  My fconv.c has 4 conversions from floats to integers, and the
table has my experimental rules that do the conversions by allocating
4 or 5 registers.
2017-02-13 17:44:46 -05:00
George Koehler dc05cb2dc8 Add pat cms !defined($1)
Switch .cms to pass inputs and outputs on the real stack, not in
registers; like we do with .and, .or (81c677d) and .xor (c578c49).

At this point, nearly all functions in libem use the real stack, not
registers, for passing inputs and outputs.  This simplifies the ncg
table (which needs fewer lists of specific registers) but slows calls
to libem.

For example, after ba9b021, each call to .aar4 is about 10
instructions slower.  I moved 3 inputs and 1 output from registers to
the real stack.  A program would take 4 instructions to move registers
to stack, 4 to move stack to registers, and perhaps 2 to adjust the
stack pointer.
2017-02-13 16:52:32 -05:00
George Koehler 89dd80e34d Add missing instances of "kills ALL" or "with STACK". 2017-02-13 16:38:26 -05:00
George Koehler ba9b021253 Use .los4 in lar 4 and .sts4 in sar 4.
Our libem had two implementations of loading a block from a stack, one
for lar 4 and one for los 4.  Now lar 4 and los 4 share the code in
.los4.  Likewise, sar 4 and sts 4 share the code in .sts4.

Rename .los to .los4 and .sts to .sts4, because they implement los 4
and sts 4.  Remove the special case for loading or storing 4 bytes,
because we can do it with 1 iteration of the loop.  Remove the lines
to "align size" where the size must already be a multiple of 4.

Fix the upper bound check in .aar4.

Change .aar4, .lar4, .los4, .sar4, .sts4 to pass all operands on the
real stack, except that .los4 and .sts4 take the size in register r3.
Have .aar4 set r3 to the size of the array element.  So lar 4 is just
.aar4 then .los4, and sar 4 is just .aar4 then .sts4.

ncg no longer calls .lar4 and .sar4 in libem, because it inlines the
code; but I keep .lar4 and .sar4 in libem, because mcg references
them.  They might or might not work in mcg.
2017-02-13 15:22:00 -05:00
George Koehler 54949f713f Change .fef8 and .fif8 to pass values on the stack.
Reorder the code in .fef8 and .fif8 so that in the usual case, we fall
through to the blr without taking any branches.  The usual case, by my
guess, is .fef8 with normalized numbers or .fif8 with small integers.

I change .fef8 and .fif8 to pass values on the real stack, not in
specific registers.  This simplifies the ncg table, and might help me
experiment with changes to the ncg table.

This change might or might not help mcg.  Seems that mcg always uses
the stack to pass values to libem, but I have not tested .fef8 or
.fif8 with mcg.
2017-02-12 16:44:37 -05:00
George Koehler 1de1e8f7f0 Experiment with conversions between integers and floats.
Switch some conversions from libem calls to inline code.  The
conversions from integers to floats are now too slow, because each
conversion allocates 4 or 5 registers, and the register allocator is
too slow.  I might use these slow conversions to experiment with the
register allocator.

I add the missing conversions between 4-byte single floats and
integers, simply by going through 8-byte double floats.  (These
replace the calls to nonexistant functions in libem.)

I remove the placeholder for fef 4, because it doesn't exist in libem,
and our language runtimes only use fef 8.
2017-02-12 15:45:28 -05:00
George Koehler 2e41c392fa Implement blm and bls using an inline loop.
This replaces a call to memmove() in libc.  That was working for me,
but it can fail because EM programs don't always link to libc.

blm and bls only need to copy aligned words.  They don't need to copy
bytes, and they don't need to copy between overlapping buffers, as
memmove() does.  So the new loop is simpler than memmove().
2017-02-11 19:30:12 -05:00
George Koehler c578c495bb Edit PowerPC assembly for .and, .cms, .ior, .xor, .zer
Remove one addi instruction from some loops.  These loops had
increased 2 pointers, they now increase 1 index.  I must initialize
the index, so I add "li r6, 0" before each loop.

Change .zer to use subf instead of neg, add.

Change .xor to take the size on the real stack, as .and and .or have
done since 81c677d.
2017-02-11 18:00:56 -05:00
George Koehler 83c13597e1 Use "mr" and make a few other tweaks in PowerPC ncg table.
Use extended "mr" instead of basic "or" to move registers.  Both "mr"
and "or" encode the same machine instruction.  With "mr", I can more
easily search the assembly output for register moves.

Fold several stacking rules into a single rule ANY_BHW-REG to STACK.

Remove the EM patterns for loc mlu $2==2 and loc slu.  The first
pattern had the wrong size (should be $2==4, not $2==2).  Both
patterns were redundant.  They rewrote loc mlu as loc mli and loc slu
as loc sli, but this table doesn't have patterns for loc mli or loc
sli, so it is enough to rewrite mlu as mli and slu as sli.
2017-02-10 11:45:50 -05:00
George Koehler 85391399a4 Use ha16/lo16 to load or store 1, 2, 8 bytes from labels.
Add the tokens IND_RL_B, IND_RL_H, IND_RL_H_S, IND_RL_D, along with
the rules to use them.  These rules emit shorter code.  For example,
loading a byte becomes lis, lbz instead of lis, addi, lbz.

While making this, I wrongly set IND_RL_D to size 4.  Then ncg made
infinite recursion in codegen() and stackupto(), until it crashed by
stack overflow.  I correctly set IND_RL_D to size 8, preventing the
crash.
2017-02-08 12:31:14 -05:00
George Koehler 5e00e1fce2 Trimming mach/powerpc/ncg/table
Remove coercion from LABEL to REG.  The coercion never happens because
I have stopped putting LABEL on the stack.  Also remove LABEL from set
ANY_BHW.  Retain the move from LABEL to REG because pat gto uses it.

Remove li32 instruction, unused after the switch to the hi16, ha16,
lo16 syntax.

Remove COMMENT(...) lines from most moves.  In my opinion, they took
too much space, both in the table and in the assembly output.  The
stacking rules and coercions keep their COMMENT(...)  lines.

In test GPR, don't write to RSCRATCH.

Fold several coercions into a single coercion from ANY_BHW uses REG.

Use REG instead of GPR in stack patterns.  REG and GPR act the same,
because every GPR on the stack is a REG, but I want to be clear that I
expect a REG, not r0.

In code rules, sort SUM_RC before SORT_RR, so I can add SUM_RL later.

Remove rules to optimize loc loc cii loc loc cii.  If $2==$4, the
peephole optimizer can optimize it.  If $2!=$4, then the EM program is
missing a conversion from size $2 to size $4.

Remove rules to store a SEX_B with sti 1 or a SEX_H with sti 2.  These
rules would never get used, unless the EM program is missing a
conversion from size 4 to size 1 or 2.
2017-02-08 12:27:16 -05:00
George Koehler ed21a59a82 In PowerPC ncg, allocate register for ha16[label].
Use it to generate code like

    lis r12,ha16[__II0]
    lis r11,ha16[_f]
    lfs f1,lo16[_f](r11)
    lfs f2,lo16[__II0](r12)
    fadds f13,f2,f1
    stfs f13,lo16[_f](r11)

Here ncg has allocated r11 for ha16[_f].  We use r11 in lfs and again
in stfs.  Before this change, we needed an extra lis before stfs,
because ncg did not remember that ha16[_f] was in a register.

This example has a gap between ha16[__II0] and lo16[__II0], because
the lo16 is not in the next instruction.  This requires my previous
commit 1bf58cf for RELOLIS.  There is a gap because ncg emits the lis
as soon as I allocate it.  The "lfs f2,lo16[__II0](r12)" happens in a
coercion from IND_RL_W to FSREG.  The coercion allocates one FSREG but
may not allocate any other registers.  So I must allocate r12 earlier.
I allocate r12 in pat lae, but this causes a gap.
2017-02-08 12:23:06 -05:00
George Koehler 754e96ef16 Use ha16/lo16 to emit pairs of lis/stw, lis/lfs, lis/stfs.
A 4-byte load from a label yields a token IND_RL_W.  This token emits
either lis/lwz or lis/lfs, if we want a general-purpose register or a
floating-point register.
2017-02-08 12:13:54 -05:00
George Koehler 7255ed403f Tweak some tokens in PowerPC ncg.
Remove the GPRINDIRECT token, and use the IND_RC_* tokens as operands
to instructions.  We no longer need to unpack an IND_RC_* token and
repack it as a GPRINDIRECT to use it in an instruction.

Allow storing IND_ALL_B and IND_ALL_H in register variables.  Create a
set ANY_BHW for anything that we can store in a regvar.

Push register variables on the stack without using GPRE, by changing
stwu to accept LOCAL.  Then ncg will replace the string ">>> BUG IN
LOCAL" with the register name.  (I copied ">>> BUG IN LOCAL" from
mach/arm/ncg/table.)

Fix the rule for "pat lil inreg($1)>0" to yield a IND_RC_W token, not
a register.  We might need to kill the token with "kills MEMORY".

Rename CONST_ALL to CONST_STACK, because it only includes constants on
the stack, and excludes CONST tokens.  Instructions still don't allow
CONST_STACK operands, so we still need to repack each CONST_STACK as a
CONST to use it in an instruction.

Rename LABEL_OFFSET_HI to just LABEL_HI, and same for LABEL_HA and
LABEL_HO.
2017-02-08 12:12:28 -05:00
George Koehler 1bf58cf51c Add RELOLIS for PowerPC lis with ha16 or hi16.
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.
2017-02-08 11:46:31 -05:00
George Koehler f4cfbedd5c Remove #include <stdbool.h> from mach/powerpc/as/mach1.c
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.
2017-01-30 16:39:23 -05:00
George Koehler 3c1d2d79f0 Remove type quad, use type word_t in PowerPC as.
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.
2017-01-30 16:15:02 -05:00
George Koehler 48e3aab728 Swap RA and RS when assembling "and", "or", and such instructions.
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.
2017-01-30 15:47:09 -05:00
George Koehler 9ddbb66c8b Turn off comments again. I turned them on by accident in c416889. 2017-01-30 15:45:46 -05:00
George Koehler c41688929c In PowerPC ncg, switch the scratch register from r11 to r0.
r0 is a special case and can't be used when adding a register to a
constant.  The few remaining users of the scratch register don't do
that.  I removed other usages of the scratch register in 7c64dab,
5b5f774, 19f0eb8, f64b7d8.
2017-01-26 13:10:08 -05:00
George Koehler 1dfd5524e4 In PowerPC top, don't delete addi r0, r0, 0
Also don't delete addis r0, r0, 0.  These instructions are special
cases that set r0 to zero.  If we delete them, then r0 keeps its old
value.

I caught this bug because osxppc protects the .text segment against
writing.  (linuxppc doesn't protect it.)  A program tried to set r0 to
the NULL pointer, but top deleted the instruction, so r0 kept an old
return address pointing into .text.  Later the program checked that r0
wasn't NULL, tried to write to address r0, and crashed.
2017-01-26 12:44:32 -05:00
George Koehler 8c8f291a07 In PowerPC libem, remove tge.s and powerpc.h
Nothing uses the tables in tge.s, after I changed the ncg table.
There are no *.e files in libem, so don't try to build them.
2017-01-26 12:39:16 -05:00
George Koehler f64b7d8ea0 Rewrite how PowerPC ncg does conditional branches and tests.
The rewritten code rules bring 3 new features:

  1.  The new rules compare a small constant with a register by
      reversing the comparison and using `cmpwi` or `cmplwi`.  The old
      rules put the constant in a register.

  2.  The new rules emit shorter code to yield the test results,
      without referencing the tables in mach/powerpc/ncg/tge.s.

  3.  The new rules use the extended `beq` and relatives, not the
      basic `bc`, in the assembly output.

I delete the old tristate tokens and the old moves, because they
confused me.  Some of the old moves weren't really moves.  For
example, `move R3, C0` and then `move C0, R0` did not move r3 to r0.

I rename C0 to CR0.
2017-01-25 19:08:55 -05:00
George Koehler a348853ece Add missing size declarations for 8-byte registers.
This fixes the coercion from IND_ALL_D to FREG.  The coercion had
never happened, because IND_ALL_D had 8 bytes but FREG had 4 bytes.
Instead, ncg always stacked the IND_ALL_D and unstacked a FREG.  The
stacking rule uses f0, so the code did load f0 with the indirect
value, push f0 to stack, load f1 to stack, move stack pointer.  Now
that FREG has 8 bytes, ncg does the coercion, and the code just loads
f1 with the indirect value.
2017-01-25 11:56:58 -05:00
George Koehler 188b23bade Add constraints for pat lab, as done in the m68020 table.
Always use 'kills ALL' when reaching a label, because our registers
and tokens have the wrong values if the program jumps to this label
from somewhere else.

When falling through a label, if the top element is in r3, then
require that the rest of the stack is in the real STACK, not in
registers or tokens.

I'm doing this to be certain that the missing constraints are not
causing bugs.  I did not find any such bug, perhaps because the labels
are usually near other instructions (like conditional branches and
function calls) that stack or kill tokens.
2017-01-24 11:26:35 -05:00
George Koehler bb67dbeb11 Use "kills ALL" instead of a list of killed registers.
This is for fef 8 and fif 8.  I changed .fef8 so it no longer kills
r7, but I don't want to update the list.  We already use "kills ALL"
for most other calls to libem.
2017-01-23 17:31:29 -05:00
George Koehler 032bcffef6 In PowerPC libem, use the new features of our assembler.
The new features are the hi16/lo16 and ha16/lo16 syntax for
relocations, and the extended mnemonics like "blr".

Use ha16/lo16 to load some double floats with 2 instructions (lis/lfd)
instead of 3 (lis/ori/lfd).

Use the extended names for branches, comparisons, and bit rotations,
so I can more easily read the code.  The new names often encode the
same machine instructions as the old names, except in a few places
where I changed the instructions.

Stop using andi. when we don't need to set cr0.  In inn.s, I change
andi. to extrwi to extract the same bits.  In los.s and sts.s, I
change "andi. r3, r3, ~3" to "clrrwi r3, r3, 2".  This avoids setting
cr0 and also stops clearing the high 16 bits of r3.

In csa.s, los.s, sts.s, I change some comparisons and right shifts
from signed to unsigned (cmplw, cmplwi, srwi), because the sizes are
unsigned.  In inn.s, the right shift can be signed (sraw) or unsigned
(srw), but I use srw because we don't need the carry bit.

In fef8.s, I save an instruction by using rlwinm instead of addis/andc
to rlwinm to clear a field.  The code no longer kills r7.  In both
fef8.s and fif8.s, I remove the list of killed registers.

Also remove some whitespace from ends of lines.
2017-01-23 17:16:39 -05:00
George Koehler 5aa2ac2246 Teach the assembler about PowerPC extended mnemonics.
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.
2017-01-21 23:49:29 -05:00
David Given 232545606d Merge from default. 2017-01-18 00:02:32 +01:00
David Given 81c677d218 Add a bunch more set operations to the PowerPC backends, and the Pascal test
for the same.
2017-01-17 22:31:38 +01:00
David Given e7e29d34ff Add a test (currently failing) to check that Pascal char sets can store all 256
possible values. Add the PowerPC ncg and mcg backend support to let the test
actually run, including modifying a bunch of PowrePC libem functions so that
they can be called from both ncg and mcg.
2017-01-15 22:28:14 +01:00
David Given 9a346c382d Turns out Apple's hi16/ha16 exactly match my ha16/has16, so renamed
accordingly. (Memo to self: read the docs *before* doing the work.)
2017-01-15 11:59:33 +01:00
David Given f80acfe9f5 Signed vs unsigned lower halves of powerpc fixups are now handled by having two
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.
2017-01-15 11:51:37 +01:00
David Given 3c0bc205fc Update the hi/lo syntax to be a bit more standard. 2017-01-15 10:21:02 +01:00
David Given 8edbff9795 Add assembler support for fixing up arbitrary oris/addi pairs of instructions;
this should allow oris/lwz constant value loads, which will save an opcode.
2017-01-15 00:15:01 +01:00