Skip to content

Commit

Permalink
Make sleep work with alpine
Browse files Browse the repository at this point in the history
  • Loading branch information
tbodt committed Aug 29, 2017
1 parent ea65057 commit da3c873
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 6 deletions.
35 changes: 34 additions & 1 deletion emu/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,40 @@ struct cpu_state {

// fpu
extFloat80_t fp[8];
unsigned top:3;
union {
word_t fsw;
struct {
bits ie:1; // invalid operation
bits de:1; // denormalized operand
bits ze:1; // divide by zero
bits oe:1; // overflow
bits ue:1; // underflow
bits pe:1; // precision
bits stf:1; // stack fault
bits es:1; // exception status
bits c0:1;
bits c1:1;
bits c2:1;
unsigned top:3;
bits c3:1;
bits b:1; // fpu busy (?)
};
};
union {
word_t fcw;
struct {
bits im:1;
bits dm:1;
bits zm:1;
bits om:1;
bits um:1;
bits pm:1;
bits pad4:2;
bits pc:2;
bits rc:2;
bits y:1;
};
};

// See comment in sys/tls.c
addr_t tls_ptr;
Expand Down
12 changes: 11 additions & 1 deletion emu/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,9 @@ int CONCAT(decoder_name, OP_SIZE)(struct cpu_state *cpu) {
case 0x97: TRACEI("xchg odi, oax");
XCHG(odi, oax,); break;

case 0x9e: TRACEI("sahf\t\t"); SAHF; break;

case 0x99: TRACEI("cdq"); CDQ; break;
// TODO make this its own macro

case 0x9c: TRACEI("pushf"); PUSHF(); break;
case 0x9d: TRACEI("popf"); POPF(); break;
Expand Down Expand Up @@ -597,7 +598,11 @@ int CONCAT(decoder_name, OP_SIZE)(struct cpu_state *cpu) {
if (modrm.type != mod_reg) {
switch (insn << 4 | modrm.opcode) {
case 0xd81: TRACE("fmul mem32"); FMUL(mem_addr_real,32); break;
case 0xd95: TRACE("fldcw mem16"); FLDCW(mem_addr); break;
case 0xd97: TRACE("fnstcw mem16"); FSTCW(mem_addr); break;
case 0xda4: TRACE("fisub mem32"); FISUB(mem_addr,32); break;
case 0xdb2: TRACE("fist mem32"); FIST(mem_addr,32); break;
case 0xdb3: TRACE("fistp mem32"); FIST(mem_addr,32); FPOP; break;
case 0xdc0: TRACE("fadd mem64"); FADDM(mem_addr_real,64); break;
case 0xdd0: TRACE("fld mem64"); FLD(mem_addr_real,64); break;
case 0xdd2: TRACE("fst mem64"); FSTM(mem_addr_real,64); break;
Expand All @@ -607,6 +612,7 @@ int CONCAT(decoder_name, OP_SIZE)(struct cpu_state *cpu) {
}
} else {
switch (insn << 4 | modrm.opcode) {
case 0xd91: TRACE("fxch st"); FXCH(); break;
case 0xd95:
switch (modrm.rm_opcode) {
case 6: TRACE("fldz"); FLDC(zero); break;
Expand All @@ -615,6 +621,10 @@ int CONCAT(decoder_name, OP_SIZE)(struct cpu_state *cpu) {
break;
case 0xdb5: TRACE("fucomi st"); FUCOMI(); break;
case 0xdd3: TRACE("fstp st"); FST(); FPOP; break;
case 0xdd4: TRACE("fucom st"); FUCOM(); break;
case 0xdd5: TRACE("fucomp st"); FUCOM(); FPOP; break;
case 0xde0: TRACE("faddp st, st(i)"); FADD(st_0, st_i); FPOP; break;
case 0xdf4: TRACE("fnstsw ax"); FSTSW(ax); break;
case 0xdf5: TRACE("fucomip st"); FUCOMI(); FPOP; break;
default: TRACE("undefined"); UNDEFINED;
}
Expand Down
6 changes: 6 additions & 0 deletions emu/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,12 @@
#define STD cpu->df = 1
#define CLD cpu->df = 0

#define AH_FLAG_MASK 0b11010101
#define SAHF \
cpu->eflags &= 0xffffff00 | ~AH_FLAG_MASK; \
cpu->eflags |= cpu->ah & AH_FLAG_MASK; \
cpu->cf_ops = cpu->pf_res = cpu->af_ops = cpu->zf_res = cpu->sf_res = 0

#include "emu/interp/sse.h"
#include "emu/interp/fpu.h"

Expand Down
34 changes: 31 additions & 3 deletions emu/interp/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#define extF80_to_f(f, z) CONCAT(extF80_to_f, sz(z))(f)
#define f_to_extF80(f_, z) CONCAT3(f, sz(z), _to_extF80)(f_)
#define extF80_to_i(i, round, exact, z) CONCAT(extF80_to_i, sz(z))(i, round, exact)
#define i_to_extF80(i_, round, exact, z) CONCAT3(i, sz(z), _to_extF80)(i_, round, exact)

#define ST(i) cpu->fp[cpu->top + i]
#define ST_i ST(modrm.rm_opcode)
Expand All @@ -21,6 +23,17 @@
#define FPOP \
cpu->top++

#define FXCH() { \
extFloat80_t tmp = ST(0); \
ST(0) = ST_i; \
ST_i = tmp; \
}

#define st_0 ST(0)
#define st_i ST(modrm.rm_opcode)

#define FADD(src, dst) \
dst = extF80_add(dst, src)
#define FADDM(val,z) \
ST(0) = extF80_add(ST(0), f_to_extF80(get(val,z),z))
#define FISUB(val,z) \
Expand All @@ -30,10 +43,16 @@

#define FUCOMI() \
cpu->zf = extF80_eq(ST(0), ST_i); cpu->zf_res = 0; \
cpu->cf = extF80_lt(ST(0), ST_i); cpu->sf_res = 0; \
cpu->cf = extF80_lt(ST(0), ST_i); cpu->cf_ops = 0; \
cpu->pf = 0; cpu->pf_res = 0
// not worrying about nans and shit yet

#define FUCOM() \
cpu->c0 = extF80_lt(ST(0), ST_i); \
cpu->c1 = 0; \
cpu->c2 = 0; /* again, not worrying about nans */ \
cpu->c3 = extF80_eq(ST(0), ST_i)

#define FILD(val,z) \
FPUSH(i64_to_extF80((sint(z)) get(val,z)))
#define FLD(val,z) \
Expand All @@ -42,7 +61,16 @@
#define FLDC(what) FPUSH(fconst_##what)
#define fconst_zero i64_to_extF80(0)

#define FSTM(val,z) \
set(val, extF80_to_f(ST(0),z),z)
#define FSTM(dst,z) \
set(dst, extF80_to_f(ST(0),z),z)
#define FIST(dst,z) \
set(dst, extF80_to_i(ST(0), softfloat_roundingMode, false, z),z)

#define FST() ST_i = ST(0)

#define FSTSW(dst) \
set(dst, cpu->fsw,16)
#define FSTCW(dst) \
set(dst, cpu->fcw,16)
#define FLDCW(dst) \
cpu->fcw = get(dst,16)
1 change: 1 addition & 0 deletions sys/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ int sys_execve(const char *file, char *const argv[], char *const envp[]) {

current->cpu.esp = sp;
current->cpu.eip = entry;
current->cpu.fcw = 0x37f;
pthread_cond_broadcast(&current->vfork_done);

err = 0;
Expand Down
3 changes: 2 additions & 1 deletion tools/ptraceomatic.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ static int compare_cpus(struct cpu_state *cpu, int pid, int undefined_flags) {
CHECK_XMMREG(6);
CHECK_XMMREG(7);

CHECK((fpregs.swd >> 11) & 7, cpu->top, "top");
CHECK(fpregs.swd, cpu->fsw, "fsw");
CHECK(fpregs.cwd, cpu->fcw, "fcw");
#define CHECK_FPREG(i) \
CHECK(*(uint64_t *) &fpregs.st_space[i * 4], cpu->fp[(cpu->top + i)%8].signif, "st(" #i ") signif") \
CHECK(*(uint16_t *) &fpregs.st_space[i*4+2], cpu->fp[(cpu->top + i)%8].signExp, "st(" #i ") sign/exp")
Expand Down

0 comments on commit da3c873

Please sign in to comment.