The system call puts the time in a pair of registers, not in the
timeval structure. Add code to move the time to the structure, so
programs see the correct time, not garbage. This fixes our example
programs that use the time as a random seed.
This preserves the name and value of every symbol. The type and other
info of a symbol might be lost. In gdb, one can now "disas main" or
"disas '.ret'" to disassemble functions by name.
Most symbols are in sections, so I also teach cvmach to emit the Mach
section headers. The entry point in plat/osx*/descr moves down to
make room for the section headers and LC_SYMTAB.
I fix some bugs in calculations of cvmach. They were wrong if ROM had
a greater alignment than TEXT, or if DATA did not start on a page
boundary. I introduce machseg[] to simplify the mess of variables in
main(). I declare most functions as static. Also, cvmach becomes the
first program to #include <object.h>.
This header declares functions in libobject. Our programs never
included object.h, but called functions in libobject without declaring
them. So, our build system never put object.h in the include path;
any #include <object.h> would fail to find the header.
With this commit, a program may #include <object.h> if it has
modules/src/object+lib in its deps.
Declare structs in object.h so we can use them in prototypes without
gcc warning, "'struct whatever' declared inside parameter list".
Remove inclusion of ansi.h from object.h. Programs would need to
depend on modules+headers to get ansi.h in the include path.
This uses uint32_t for the base, file offset, and alignment of each
section, to be consistent with the usage of uint32_t in h/out.h
Also declare setbit() as static.
Before this commit, the headers in plat/osx/include got installed
twice into PLATIND/osx386/include and PLATIND/osxppc/include. This
commit installs them once into PLATIND/osx/include and changes both
descr files to find them.
Several rules in lang/ depend on plat/osx386/include+headers or
plat/osxppc/include+headers. They each become a simplerule that
depends on plat/osx/include+headers.
Rename our getline() to get_line() to prevent a conflict with POSIX
getline() declared in stdio.h.
Remove dangerous call to gets(). OpenBSD does not have gets(), C99
deprecated it and C11 removed it.
Also change spelling "sheild" to "shield".
This fixes flt_arith2flt() when sizeof(arith) != 4, where arith is
long. When cemcom.ansi sees an expression like d + 1 (where d is some
double), it calls flt_arith2flt() to convert 1 to floating-point. On
machines where sizeof(arith) != 4, the code did n >>= 1 when n should
not have been changed. If n was 1, then n == 0 became true. This
caused the code to convert 1 or -1 to 0.0.
My fix assumes sizeof(arith) >= 8, so I can use n >> 32. Machines
with sizeof(arith) of 5 to 7 would need to do (uarith)n >> 32, where
uarith must be an unsigned integer type of same size as arith.
In startrek.c, the Enterprise can now dock with a starbase. The
compiler no longer translates s1 - 1 to s1 - 0.0 and s1 + 1 to s1 +
0.0, so the game now looks for starbases next to the Enterprise.
This undoes part of bfeb736, and returns to using DBL_MAX_EXP and
DBL_MIN_EXP from float.h.
Add a dependency on math/localmath.h and other local header files so
libc is rebuilt when those headers change.
This restores the correct values of DBL_MAX, DBL_MIN_EXP, and related
constants. This fixes some range checks within libc, causing
atof("-36e90") and atof("1.44e-288") to return the correct values.
It seems that someone wanted to build flt_arith with a compiler that
had long but not unsigned long. This required extra code to
accomplish unsigned right shift, unsigned division, and unsigned
comparison using the signed operations. Now that we use uint32_t, we
can simply use the unsigned operations and remove the ucmp() function.
We have similar code in mach/proto/fp/ and in
lang/cem/libcc.ansi/stdlib/ext_comp.c where we use the unsigned
operations.
Some long variables become uint32_t, and some masks with 0xFFFFFFFF
disappear because uint32_t has only 32 bits.
Update flt_arith.3 to show that mantissa uses uint32_t.
Provide a target to install modules/src/flt_arith/test.c as flt_test
so I can run the tests.
This seems to fix an error when flt_arith converts a literal
double-precision float to IEEE format. For example, 0.5 and 0.75 got
converted to slightly below their correct values.
My host gcc for amd64 has 64-bit long, but flt_arith needs only 32
bits. The code (at least flt_add.c) can make 32-bit overflows. Such
overflows would set the higher bits of a 64-bit long, which might
cause problems later.
I need to use uint32_t and not int32_t because the code still uses
long, and the sign extension from int32_t to long would cause
problems. The mantissa represents a value in [0, 2) that can't be
negative, so unsigned type is better. Also, signed overflow is
undefined behavior in C, so flt_add.c better make overflows with
uint32_t and not int32_t.
This commit doesn't touch lang/cem/libcc.ansi/stdlib/ext_fmt.h which
continues to use unsigned long for its mantissa fields.
This would have happened later, if f14 to f31 became regvar (like r13
to r31 are now). I am doing it now because ncg is too slow for rules
"with FREG FREG uses FREG". We use such rules for adf 8 and other EM
instructions that operate on 2 floats. Like my last commit cfbc537,
this commit speeds ncg by removing choices for register allocation.
ncg is too slow with this many registers. A stack pattern "with GPR
GPR GPR" or "with REG REG REG" takes too long to pick registers,
causing ncg 8 to take about 2 seconds on each sti 8. I introduce
REG_PAIR and there are only 4 such pairs.
For programs that use sti 8 (including C programs that copy 8-byte
structs), this speed hack improves the ncg run from several seconds to
almost instantaneous.
Also add a few COMMENT(...) lines in stacking rules.
This fixes the SIGILL (illegal instruction) in startrek when firing
phasers. The 32-bit processors in my PowerPC Mac and in QEMU don't
have fctid, a 64-bit instruction.
I got the idea from mach/proto/fp/fif8.c to extract the exponent,
clear some bits to get an integer, then subtract the integer from
the original value to get the fraction.
Adjust some of the loi rules (and associated moves) so we can identify
the tokens that must be in MEMORY.
With this commit, I can navigate the Enterprise even if I comment out
my work-around from e22c888.
Because li32 always loads a label into a GPR, it is sufficient to
coerce LABEL to REG, then use IND_RC_W or IND_RC_D for indirection
through the label.
Now that SUM_RC always has a signed 16-bit constant, it happens that
the various IND_RC_* tokens also have a signed 16-bit constant, so
we no longer need to touch the scratch register.
When loc (load constant) pushes a constant, it now checks the value of
the constant and pushes any of 7 tokens. These tokens allow stack
patterns to recognize 16-bit signed integers (CONST2), 16-bit unsigned
integers (UCONST2), multiples of 0x10000 (CONST_HZ), and other
interesting forms of constants.
Use the new constant tokens in the rules for adi, sbi, and, ior, xor.
Adjust a few other rules to understand the new tokens.
Require that SUM_RC has a signed 16-bit constant, and OR_RC and XOR_RC
each have an unsigned 16-bit constant. The moves from SUM_RC, OR_RC,
XOR_RC to GPR no longer touch the scratch register, because the
constant is not too big.
Change the operator in his() from a - minus to a + plus. When los(n)
becomes negative, then his(n) needs to add 0x10000, not subtract it.
Also change los(n) to do the sign extension, because smalls(los(n))
should be true, not false.
Also change hi(n) and lo(n) to wrap n in parentheses, as (n), because
these are macros and n might still contain operators.
This feature has never been used since its introduction, more than 3
years ago, in David Given's commit c93cb69 of May 8, 2013. The commit
was for "PowerPC and M68K work". I am not undoing the entire commit.
I am only removing the stackadjust and stackoffset() feature.
This commit removes the feature from my branch kernigh-linuxppc. This
removal includes the mach/proto/ncg parts. The default branch already
removed most of the feature, but kept the mach/proto/ncg parts. That
removal happened in commit 81778b6 of May 13, 2013 (which was a merge;
git diff af0dede81778b6). The branch dtrg-experimental-powerpc
merged the default branch but without the removal. That merge was
commit 4703db0f of Sep 15, 2016 (git diff 8c94b134703db0). My branch
kernigh-linuxppc is off branch dtrg-experimental-powerpc, so I can no
longer get the removal by merging default.
David Given described the stackadjust feature in
https://sourceforge.net/p/tack/mailman/message/30814691/
The instruction stackadjust would add a value to the offset, and the
function stackoffset() would return this offset. One would use this
to track sp - fp, then omit the frame pointer by not keeping fp in a
register.
We only need GPRE in a few places where we write {GPRE, regvar(...)}
because ncgg can't parse plain regvar(...). In all other places, a
plain GPR works.
Also remove gpr_gpr_gpr and a few other unused and fake instructions
from the list of instructions.
Rename the scratch gpr (currently r11) from SCRATCH to RSCRATCH so I
can search for RSCRATCH without finding FSCRATCH. I also want to
avoid confusion with the SCRATCH keyword of the old code generator (cg
which came before ncg).
Change the stacking rules to prevent stacking of RSCRATCH or FSCRATCH
or any other GPR or FPR that isn't an allocatable REG or FREG. Then
ncgg rejects any rule that tries to stack a GPR or FPR, so change such
rules to stack a REG or FREG.
These produce Mach-o executables for Mac OS X on Intel or PowerPC
processors. Our code generator for PowerPC (mach/powerpc) still has
bugs. Some examples seem to run, but startrek crashes. Our code
generator for Intel (mach/i386) is better.
There is a problem with job control. If you run paranoia or startrek,
then suspend the job (^Z) and resume it ('fg' in bash), then read(2)
might fail with EINTR.
The larger files in this commit are
- plat/osx/cvmach/cvmach.c
- plat/osx/libsys/brk.c
- plat/osx386/libsys/sigaction.s
- plat/osxppc/libsys/sigaction.s
I copied the definitions from linux386 and linux68k.
This change also moves _errno and the other common symbols in boot.s
from .text to .bss. Common symbols belong in .bss, but the assembler
seems dumb enough to put them in any section.
In our powerpc table, sdl fails to kill the old value of the local.
This is a bug, because a later ldl can load the old value instead of
the newly stored value. By rewriting "sdl 0" "ldl 0" as "dup 8" "sdl
0", the newly added rule works around the bug, but only when the ldl
is immediately after the sdl.
This rule improves code that uses double-precision floating point.
The output of printf("%f", 6.0) in C changes from all zero digits to
"6000000" but still doesn't print the decimal point. The result of
atof("-123.456") becomes correct. In startrek, I can now move the
Enterprise, but I still can't fire phasers without crashing the game.
We already have a rule for stl lol $1==$2. We had two copies of the
rule, so I am deleting the second copy.
In EM, fef splits a float into exponent and fraction. The old C code,
given an infinite float, got stuck in an infinite loop. The new
assembly code doesn't loop; it extracts the IEEE exponent.
This fixes code that tried to "addi SP, SP, 4" to drop a value that
was in a register, not on the real stack.
Add a rule to optimize "asp 4" (which becomes "loc 4" "ass") when
the value being dropped is already in a GPR.
When ncg fell back on this rule, it did emit the string "invalid" in
the assembly code and caused a syntax error in the assembler.
Adjust the stacking rules so we can stack LOCAL, CONST, and LABEL
without falling back on the "invalid" rule, and so we can stack them
when we have no free register except the scratch register.
Don't define __POWERPC. I don't know any other compiler that defines
__POWERPC and don't want to invent a new macro. Apple's gcc 4.0.1
from Xcode 2.5 defines __ppc__, _ARCH_PPC, __POWERPC__. Debian's gcc
4.9.2-10 defines _ARCH_PPC, __PPC__, __powerpc__, __PPC, __powerpc,
PPC, powerpc.
Move the base vm address from 0x80000000 down to 0x10000000, as this
is where Debian loads /bin/true. This is still higher than the base
addresses for linux386 and linux68k.
Sync led's arguments with linux386.