mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Add The LISP Challenge
This change introduces a 2.5kb program that's comes pretty close so far to bootstrapping John McCarthy's metacircular evaluator on bare metal.
This commit is contained in:
parent
fd22e55b42
commit
b6793d42d5
34 changed files with 1056 additions and 358 deletions
7
third_party/stb/stb.mk
vendored
7
third_party/stb/stb.mk
vendored
|
@ -63,10 +63,11 @@ $(THIRD_PARTY_STB_A_OBJS): \
|
|||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
o/$(MODE)/third_party/stb/stb_image_write.o \
|
||||
o/$(MODE)/third_party/stb/stb_image.o: \
|
||||
o//third_party/stb/stb_image_write.o \
|
||||
o//third_party/stb/stb_image.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-ftrapv
|
||||
-ftrapv \
|
||||
-fsanitize=address
|
||||
|
||||
$(THIRD_PARTY_STB_A_OBJS): \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
|
|
5
third_party/xed/x86.h
vendored
5
third_party/xed/x86.h
vendored
|
@ -361,8 +361,8 @@ struct XedOperands { /*
|
|||
bool rexx : 1; // rex.x or rex.wx or etc. see sib table
|
||||
bool rexrr : 1; // evex
|
||||
bool asz : 1; // address size override
|
||||
int64_t disp; // displacement(%xxx) sign-extended
|
||||
uint64_t uimm0; // $immediate sign-extended
|
||||
int64_t disp; // displacement(%xxx) mostly sign-extended
|
||||
uint64_t uimm0; // $immediate mostly sign-extended
|
||||
bool out_of_bytes : 1;
|
||||
bool is_intel_specific : 1;
|
||||
bool ild_f2 : 1;
|
||||
|
@ -383,6 +383,7 @@ struct XedOperands { /*
|
|||
uint8_t rep : 2; // 0, 2 (0xf2 repnz), 3 (0xf3 rep/repe)
|
||||
uint8_t has_modrm : 2;
|
||||
bool imm_signed : 1; // internal
|
||||
bool disp_unsigned : 1; // internal
|
||||
uint8_t seg_ovd : 3; // XED_SEG_xx
|
||||
uint8_t error : 5; // enum XedError
|
||||
uint8_t mode : 2; // real,legacy,long
|
||||
|
|
79
third_party/xed/x86ild.greg.c
vendored
79
third_party/xed/x86ild.greg.c
vendored
|
@ -130,8 +130,8 @@ static const struct XedDenseMagnums {
|
|||
xed_bits_t OSZ_NONTERM_REFINING66_EOSZ[2][2][3];
|
||||
} kXed = {
|
||||
.vex_prefix_recoding = {0, 1, 3, 2},
|
||||
.BRDISPz_BRDISP_WIDTH = {0x00, 0x10, 0x20, 0x20},
|
||||
.MEMDISPv_DISP_WIDTH = {0x00, 0x10, 0x20, 0x40},
|
||||
.BRDISPz_BRDISP_WIDTH = {0, 16, 32, 32},
|
||||
.MEMDISPv_DISP_WIDTH = {0, 16, 32, 64},
|
||||
.SIMMz_IMM_WIDTH = {0x00, 0x10, 0x20, 0x20},
|
||||
.UIMMv_IMM_WIDTH = {0x00, 0x10, 0x20, 0x40},
|
||||
.ASZ_NONTERM_EASZ =
|
||||
|
@ -786,6 +786,28 @@ privileged static void xed_evex_scanner(struct XedDecodedInst *d) {
|
|||
}
|
||||
}
|
||||
|
||||
privileged static uint64_t xed_read_number(uint8_t *p, size_t n, bool s) {
|
||||
switch (s << 2 | bsr(n)) {
|
||||
case 0b000:
|
||||
return *p;
|
||||
case 0b100:
|
||||
return (int8_t)*p;
|
||||
case 0b001:
|
||||
return READ16LE(p);
|
||||
case 0b101:
|
||||
return (int16_t)READ16LE(p);
|
||||
case 0b010:
|
||||
return READ32LE(p);
|
||||
case 0b110:
|
||||
return (int32_t)READ32LE(p);
|
||||
case 0b011:
|
||||
case 0b111:
|
||||
return READ64LE(p);
|
||||
default:
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
privileged static void xed_evex_imm_scanner(struct XedDecodedInst *d) {
|
||||
uint64_t uimm0;
|
||||
uint8_t *itext, *imm_ptr;
|
||||
|
@ -829,34 +851,9 @@ privileged static void xed_evex_imm_scanner(struct XedDecodedInst *d) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
imm_ptr = itext + d->op.pos_imm;
|
||||
if (imm_bytes) {
|
||||
switch (d->op.imm_signed << 2 | bsr(imm_bytes)) {
|
||||
case 0b000:
|
||||
d->op.uimm0 = *imm_ptr;
|
||||
break;
|
||||
case 0b100:
|
||||
d->op.uimm0 = (int8_t)*imm_ptr;
|
||||
break;
|
||||
case 0b001:
|
||||
d->op.uimm0 = READ16LE(imm_ptr);
|
||||
break;
|
||||
case 0b101:
|
||||
d->op.uimm0 = (int16_t)READ16LE(imm_ptr);
|
||||
break;
|
||||
case 0b010:
|
||||
d->op.uimm0 = READ32LE(imm_ptr);
|
||||
break;
|
||||
case 0b110:
|
||||
d->op.uimm0 = (int32_t)READ32LE(imm_ptr);
|
||||
break;
|
||||
case 0b011:
|
||||
case 0b111:
|
||||
d->op.uimm0 = READ64LE(imm_ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
d->op.uimm0 =
|
||||
xed_read_number(itext + d->op.pos_imm, imm_bytes, d->op.imm_signed);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1026,6 +1023,7 @@ privileged static void XED_LF_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2(
|
|||
x->op.disp_width =
|
||||
kXed.BRDISPz_BRDISP_WIDTH[kXed.OSZ_NONTERM_EOSZ[x->op.rexw][x->op.osz]
|
||||
[x->op.mode]];
|
||||
x->op.disp_unsigned = true;
|
||||
}
|
||||
|
||||
privileged static void XED_LF_RESOLVE_BYREG_DISP_map0x0_op0xc7_l1(
|
||||
|
@ -1046,6 +1044,7 @@ privileged static void XED_LF_MEMDISPv_DISP_WIDTH_ASZ_NONTERM_EASZ_l2(
|
|||
struct XedDecodedInst *x) {
|
||||
x->op.disp_width =
|
||||
kXed.MEMDISPv_DISP_WIDTH[kXed.ASZ_NONTERM_EASZ[x->op.asz][x->op.mode]];
|
||||
x->op.disp_unsigned = true;
|
||||
}
|
||||
|
||||
privileged static void XED_LF_BRDISP32_BRDISP_WIDTH_CONST_l2(
|
||||
|
@ -1056,15 +1055,14 @@ privileged static void XED_LF_BRDISP32_BRDISP_WIDTH_CONST_l2(
|
|||
privileged static void XED_LF_DISP_BUCKET_0_l1(struct XedDecodedInst *x) {
|
||||
if (x->op.mode <= XED_MODE_LEGACY) {
|
||||
XED_LF_BRDISPz_BRDISP_WIDTH_OSZ_NONTERM_EOSZ_l2(x);
|
||||
x->op.disp_unsigned = false;
|
||||
} else if (x->op.mode == XED_MODE_LONG) {
|
||||
XED_LF_BRDISP32_BRDISP_WIDTH_CONST_l2(x);
|
||||
}
|
||||
}
|
||||
|
||||
privileged static void xed_disp_scanner(struct XedDecodedInst *d) {
|
||||
uint8_t *disp_ptr;
|
||||
xed_bits_t length, disp_width, disp_bytes, max_bytes;
|
||||
const xed_bits_t ilog2[] = {99, 0, 1, 99, 2, 99, 99, 99, 3};
|
||||
length = d->length;
|
||||
if (d->op.map < XED_ILD_MAP2) {
|
||||
switch (xed_disp_bits_2d[d->op.map][d->op.opcode]) {
|
||||
|
@ -1095,23 +1093,8 @@ privileged static void xed_disp_scanner(struct XedDecodedInst *d) {
|
|||
if (disp_bytes) {
|
||||
max_bytes = d->op.max_bytes;
|
||||
if (length + disp_bytes <= max_bytes) {
|
||||
disp_ptr = d->bytes + length;
|
||||
switch (ilog2[disp_bytes]) {
|
||||
case 0:
|
||||
d->op.disp = *(int8_t *)disp_ptr;
|
||||
break;
|
||||
case 1:
|
||||
d->op.disp = (int16_t)READ16LE(disp_ptr);
|
||||
break;
|
||||
case 2:
|
||||
d->op.disp = (int32_t)READ32LE(disp_ptr);
|
||||
break;
|
||||
case 3:
|
||||
d->op.disp = (int64_t)READ64LE(disp_ptr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
d->op.disp =
|
||||
xed_read_number(d->bytes + length, disp_bytes, !d->op.disp_unsigned);
|
||||
d->op.pos_disp = length;
|
||||
d->length = length + disp_bytes;
|
||||
} else {
|
||||
|
|
2
third_party/xed/x86tab.S
vendored
2
third_party/xed/x86tab.S
vendored
|
@ -258,7 +258,7 @@ xed_imm_bits_2d.rodata:
|
|||
.byte 1,0x07 # 69─69 i
|
||||
.byte 2,0x05 # 6a─6b j─k
|
||||
.byte 20,0x01 # 6c─7f l─⌂
|
||||
.byte 1,0x05 # 80─80 Ç
|
||||
.byte 1,0x05 # 80─80 Ç
|
||||
.byte 1,0x07 # 81─81 ü
|
||||
.byte 2,0x05 # 82─83 é─â
|
||||
.byte 22,0x01 # 84─99 ä─Ö
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue