Dumping a lot of new FPU-related changes in a new branch

A/UX doesn't even come close to booting yet with the new FPU,
but we're getting there. I don't want to trash master with
a code base that doesn't work. Also, I turned off ethernet
in the cocoa GUI, since the TAP driver isn't working right
on 10.10 yet.
This commit is contained in:
Peter Rutenbar 2014-11-05 13:38:51 -05:00
parent a155eb7734
commit 688199cf6d
10 changed files with 140 additions and 88 deletions

View File

@ -6,8 +6,8 @@ CFLAGS = -O3 -ggdb -flto -Wno-deprecated-declarations
DEPS = mc68851.h shoebill.h Makefile macro.pl
NEED_DECODER = cpu dis
NEED_PREPROCESSING = adb fpu mc68851 mem via floppy core_api
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet
NEED_PREPROCESSING = adb mc68851 mem via floppy core_api newfpu
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet SoftFloat/softfloat
# Object files that can be compiled directly from the source
OBJ_NEED_NOTHING = $(patsubst %,$(TEMP)/%.o,$(NEED_NOTHING))
@ -78,6 +78,7 @@ $(TEMP)/decoder_gen: decoder_gen.c $(DEPS)
$(TEMP):
mkdir -p $(TEMP)
mkdir -p $(TEMP)/SoftFloat
clean:
rm -rf $(TEMP)

View File

@ -651,7 +651,7 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
shoe.pool = p_new_pool(NULL);
fpu_setup_jump_table();
fpu_initialize();
// Try to load the ROM
if (config->rom_path == NULL) {
@ -823,11 +823,7 @@ void shoebill_restart (void)
shoe.psr.word = 0;
// Reset all FPU registers
shoe.fpiar = 0;
shoe.fpcr.raw = 0;
shoe.fpsr.raw = 0;
memset(shoe.fp, 0, sizeof(shoe.fp));
fpu_reset();
// Free the old unix coff_file,
coff_free(shoe.coff);
@ -1017,7 +1013,7 @@ void slog(const char *fmt, ...)
{
va_list args;
return ;
// return ;
va_start(args, fmt);
vprintf(fmt, args);

View File

@ -1398,7 +1398,7 @@ static void inst_cas (void) {
~decompose(ext, 0000 000 uuu 000 ccc);
const uint8_t sz = (1 << s) >> 1; // (01 -> byte, 10 -> word, 11 -> long)
call_ea_read(M, sz);
/* The dest/source/result operands are reversed here from inst_cmp */
@ -1412,7 +1412,7 @@ static void inst_cas (void) {
const _Bool Dm = ea_n(sz);
const _Bool Rm = mib(R, sz);
const _Bool z = (chop(R, sz) == 0);
if (z) {
// "If the operands are equal, the instruction writes the
// update operand (Du) to the effective address operand"

View File

@ -1493,14 +1493,8 @@ void begin_definitions()
/* --- FPU (68881) instructions --- */
{
inst_t *inst = new_inst("fpu_decode", "2", 1);
add_range(inst, "1111 001 xxx xxxxxx");
no_ea(inst);
}
/* { // all other fpu ops
inst_t *inst = new_inst("fpu_decode", "2", 1);
{ // all other fpu ops
inst_t *inst = new_inst("fpu_other", "2", 1);
add_range(inst, "1111 001 000 MMMMMM");
ea_all(inst);
}
@ -1511,9 +1505,30 @@ void begin_definitions()
ea_data_alterable(inst);
}
{ // FDBcc
inst_t *inst = new_inst("fdbcc", "2", 1);
add_range(inst, "1111 001 001 001xxx");
no_ea(inst);
}
{ // FTRAPcc
inst_t *inst = new_inst("ftrapcc", "2", 1);
add_range(inst, "1111 001 001 111 010");
add_range(inst, "1111 001 001 111 011");
add_range(inst, "1111 001 001 111 100");
no_ea(inst);
}
{ // FBcc
inst_t *inst = new_inst("fbcc", "2", 1);
add_range(inst, "1111 001 01x xxxxxx");
sub_range(inst, "1111 001 010 000000"); // fnop
no_ea(inst);
}
{ // fnop
inst_t *inst = new_inst("fnop", "2", 1);
add_range(inst, "1111 001 010 000000");
no_ea(inst);
}
@ -1529,7 +1544,7 @@ void begin_definitions()
add_range(inst, "1111 001 101 MMMMMM");
ea_control(inst);
ea_add_mode(inst, EA_011);
}*/
}
}

View File

@ -1516,6 +1516,39 @@ void dis_mc68851_decode() {
assert(!"never get here");
}
void dis_fscc () {
sprintf(dis.str, "fscc??");
}
void dis_fbcc () {
sprintf(dis.str, "fbcc??");
}
void dis_fsave () {
sprintf(dis.str, "fsave??");
}
void dis_frestore () {
sprintf(dis.str, "frestore??");
}
void dis_fpu_other () {
sprintf(dis.str, "fpu_other??");
}
void dis_fdbcc () {
sprintf(dis.str, "fdbcc??");
}
void dis_ftrapcc () {
sprintf(dis.str, "ftrapcc??");
}
void dis_fnop () {
const uint16_t ext = dis_next_word();
sprintf(dis.str, "fnop");
}
#include "dis_decoder_guts.c"
/*

View File

@ -172,7 +172,7 @@ void throw_address_error()
shoe.abort = 1;
}
static void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
{
// set supervisor bit
set_sr_s(1);

View File

@ -157,6 +157,7 @@ static fpu_inst_name_t fpu_decode_op(uint16_t op, uint16_t ext)
case ~b(0011111): return fpu_inst_fgetman;
case ~b(0100001): return fpu_inst_fmod;
case ~b(0100100): return fpu_inst_fsgldiv;
case ~b(0100111): return fpu_inst_fsglmul;
case ~b(0100101): return fpu_inst_frem;
case ~b(0100110): return fpu_inst_fscale;
case ~b(0111000): return fpu_inst_fcmp;
@ -1346,8 +1347,9 @@ void inst_fmath(uint16_t op, uint16_t ext)
case ~b(0100001):
// don't forget to set fpu_set_fpsr_quotient();
assert(!"fpu_inst_fmod;");
case ~b(0100100): assert(!"fpu_inst_fsgldiv");
case ~b(0100100): assert(!"fpu_inst_fsgldiv;");
case ~b(0100101): { // fpu_inst_frem
assert(source != 0.0);
result = remainderl(dest, source);
@ -1513,6 +1515,7 @@ void fpu_setup_jump_table()
fpu_inst_fgetman,
fpu_inst_fmod,
fpu_inst_fsgldiv,
fpu_inst_fsglmul,
fpu_inst_frem,
fpu_inst_fscale,
fpu_inst_fcmp,

View File

@ -468,10 +468,21 @@ got_data:
char float128_is_nan(float128 a);
char float128_is_signaling_nan (float128 a);
/*
* s -> sign, e -> biased exponent
* ma -> 48 high bits of the mantissa
* mb -> 64 low bits of the mantissa
*/
#define _assemble_float128(s, e, ma, mb) ({ \
const uint64_t _ma = (ma), _mb = (mb); \
float128 f = { \
.high = (((s) != 0) << 16) | ((e) & 0x7fff), \
.low = _mb \
}; \
f.high = ((f.high) << 48) | _ma; \
f; \
})
// 80-bit macros, (should be 128 bit!)
// #define is_nan(f) (((f).low << 1) && (((f).high << 1) == 0xfffe))
// #define is_signal_nan(f) (is_nan((f)) && ((((f).low >> 62) & 1) == 0))
static void inst_fmath_fmovecr (void)
{
@ -481,63 +492,86 @@ static void inst_fmath_fmovecr (void)
* FYI: these constants are stored in the "intermediate" 85-bit
* format in the 6888x rom. This has the side effect that
* they are rounded according to fpcr.mc_rnd.
* We emulate the 85-bit format with float128.
* We emulate the intermediate 85-bit format with float128.
*/
switch (fpu->fmath_op) {
case 0x00: // pi
fpu->result = _assemble_float128(0, 0x4000, 0x921fb54442d1, 0x8469898cc51701b8);
break;
case 0x0b: // log_10(2)
fpu->result = _assemble_float128(0, 0x3ffd, 0x34413509f79f, 0xef311f12b35816f9);
break;
case 0x0c: // e
fpu->result = _assemble_float128(0, 0x4000, 0x5bf0a8b14576, 0x95355fb8ac404e7a);
break;
case 0x0d: // log_2(e)
// FIXME: 68881 doesn't set inex2 for this one
// (are the three intermediate bits zeros? I didn't check)
fpu->result = _assemble_float128(0, 0x3fff, 0x71547652b82f, 0xe1777d0ffda0d23a);
break;
case 0x0e: // log_10(e)
fpu->result = _assemble_float128(0, 0x3ffd, 0xbcb7b1526e50, 0xe32a6ab7555f5a67);
break;
case 0x0f: // 0.0
fpu->result = _assemble_float128(0, 0, 0, 0);
break;
case 0x30: // ln(2)
fpu->result = _assemble_float128(0, 0x3ffe, 0x62e42fefa39e, 0xf35793c7673007e5);
break;
case 0x31: // ln(10)
fpu->result = _assemble_float128(0, 0x4000, 0x26bb1bbb5551, 0x582dd4adac5705a6);
break;
case 0x32: // 1 (68kprm has typesetting issues everywhere. This one says 100, but means 10^0.)
fpu->result = _assemble_float128(0, 0x3fff, 0x0, 0x0);
break;
case 0x33: // 10
fpu->result = _assemble_float128(0, 0x4002, 0x400000000000, 0x0);
break;
case 0x34: // 10^2
fpu->result = _assemble_float128(0, 0x4005, 0x900000000000, 0x0);
break;
case 0x35: // 10^4
fpu->result = _assemble_float128(0, 0x400c, 0x388000000000, 0x0);
break;
case 0x36: // 10^8
fpu->result = _assemble_float128(0, 0x4019, 0x7d7840000000, 0x0);
break;
case 0x37: // 10^16
fpu->result = _assemble_float128(0, 0x4034, 0x1c37937e0800, 0x0);
break;
case 0x38: // 10^32
fpu->result = _assemble_float128(0, 0x4069, 0x3b8b5b5056e1, 0x6b3be04000000000);
break;
case 0x39: // 10^64
fpu->result = _assemble_float128(0, 0x40d3, 0x84f03e93ff9f, 0x4daa797ed6e38ed6);
break;
case 0x3a: // 10^128
fpu->result = _assemble_float128(0, 0x41a8, 0x27748f9301d3, 0x19bf8cde66d86d62);
break;
case 0x3b: // 10^256
fpu->result = _assemble_float128(0, 0x4351, 0x54fdd7f73bf3, 0xbd1bbb77203731fd);
break;
case 0x3c: // 10^512
fpu->result = _assemble_float128(0, 0x46a3, 0xc633415d4c1d, 0x238d98cab8a978a0);
break;
case 0x3d: // 10^1024
fpu->result = _assemble_float128(0, 0x4d48, 0x92eceb0d02ea, 0x182eca1a7a51e316);
break;
case 0x3e: // 10^2048
fpu->result = _assemble_float128(0, 0x5a92, 0x3d1676bb8a7a, 0xbbc94e9a519c6535);
break;
case 0x3f: // 10^4096
fpu->result = _assemble_float128(0, 0x7525, 0x88c0a4051441, 0x2f3592982a7f0094);
break;
default:
/*
* I wanted to include the actual values for the other ROM offsets,
* but they might be proprietary. Most of them are 0 anyways, and some
* cause FPU exceptions, even with all exceptions disabled... (?)
* (Also, looking at the micro/nanocode on a high res 68881/2 die pic,
* I can't figure out where these constants are stored.)
* 68040 FPSP just returns 0, so we'll do that too.
*/
// FIXME: 0.0 -> result
fpu->result = _assemble_float128(0, 0, 0, 0);
return ;
}
}

View File

@ -793,61 +793,11 @@ typedef struct {
} bits;
} psr;
// FPU registers
uint32_t fpiar; // FPU iaddr
// fpu_state_t pointer
// (declared here as a void*, to prevent other files
// from needing to include SoftFloat/softfloat.h)
void *fpu_state;
union { // fpcr, fpu control register
struct {
// Mode control byte
uint16_t mc_zero : 4; // zero/dummy
uint16_t mc_rnd : 2; // rounding mode
uint16_t mc_prec : 2; // rounding precision
// Exception enable byte
uint16_t ee_inex1 : 1; // inexact decimal input
uint16_t ee_inex2 : 1; // inxact operation
uint16_t ee_dz : 1; // divide by zero
uint16_t ee_unfl : 1; // underflow
uint16_t ee_ovfl : 1; // overflow
uint16_t ee_operr : 1; // operand error
uint16_t ee_snan : 1; // signalling not a number
uint16_t ee_bsun : 1; // branch/set on unordered
} b;
uint16_t raw;
} fpcr;
union { // fpsr, fpu status register
struct {
// Accrued exception byte
uint32_t dummy1 : 3; // dummy/zero
uint32_t ae_inex : 1; // inexact
uint32_t ae_dz : 1; // divide by zero
uint32_t ae_unfl : 1; // underflow
uint32_t ae_ovfl : 1; // overflow
uint32_t ae_iop : 1; // invalid operation
// Exception status byte
uint32_t es_inex1 : 1; // inexact decimal input
uint32_t es_inex2 : 1; // inxact operation
uint32_t es_dz : 1; // divide by zero
uint32_t es_unfl : 1; // underflow
uint32_t es_ovfl : 1; // overflow
uint32_t es_operr : 1; // operand error
uint32_t es_snan : 1; // signalling not a number
uint32_t es_bsun : 1; // branch/set on unordered
// Quotient byte
uint32_t qu_quotient : 7;
uint32_t qu_s : 1;
// Condition code byte
uint32_t cc_nan : 1; // not a number
uint32_t cc_i : 1; // infinity
uint32_t cc_z : 1; // zero
uint32_t cc_n : 1; // negative
uint32_t dummy2 : 4; // dummy/zero
} b;
uint32_t raw;
} fpsr;
long double fp[8]; // 80 bit floating point general registers
// -- Interrupts/VIA chips --
@ -878,9 +828,26 @@ typedef struct {
extern global_shoebill_context_t shoe; // declared in cpu.c
// fpu.c functions
void inst_fpu_decode(void);
void dis_fpu_decode(void);
void fpu_setup_jump_table();
void inst_fscc();
void inst_fbcc();
void inst_fsave();
void inst_frestore();
void inst_ftrapcc();
void inst_fdbcc();
void inst_fnop();
void inst_fpu_other();
void dis_fscc();
void dis_fbcc();
void dis_fsave();
void dis_frestore();
void dis_ftrapcc();
void dis_fdbcc();
void dis_fnop();
void dis_fpu_other();
void fpu_initialize();
void fpu_reset();
// cpu.c fuctions
void cpu_step (void);
@ -895,6 +862,7 @@ void throw_illegal_instruction();
void throw_privilege_violation();
void throw_divide_by_zero();
void throw_frame_two (uint16_t sr, uint32_t next_pc, uint32_t vector_num, uint32_t orig_pc);
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num);
// mem.c functions

View File

@ -373,8 +373,10 @@ void pram_callback (void *param, const uint8_t addr, const uint8_t byte)
[self createScreenWindow:9 height:height width:width];
uint8_t ethernet_addr[6] = {0x00, 0x24, 0x7e, 0x14, 0xd7, 0xff};
shoebill_install_ethernet_card(&config, 13, ethernet_addr);
// If you feel the cravin' for TAP-based ethernet, uncomment these lines
//
// uint8_t ethernet_addr[6] = {0x00, 0x24, 0x7e, 0x14, 0xd7, 0xff};
// shoebill_install_ethernet_card(&config, 13, ethernet_addr);
shoebill_start();