code wiki / (root) / nx_isa_s390x_gate.nx

nx_isa_s390x_gate.nx

buildroot/runtime/nx_isa_s390x_gate.nx

38247 B945 linesdepth 4pulls 5 transitivereach 0 importersview sourcekind gate/prooftopic isa
docsdependenciesstructsconstsfunctions

about

nx_isa_s390x_gate.nx -- THE s390x CONFORMANCE RULER. WHY IT EXISTS: nx_isa_conform_gate measures rv64, mips64, arm64, riscv32 and ppc64le and names s390x in its own output as UNMEASURED. An emulator nobody runs machine code through is a claim, not a capability. This organ decides "we emulate IBM z/Architecture" by RUNNING s390x machine code, in process, against values taken FROM THE z/ARCHITECTURE PRINCIPLES OF OPERATION -- never from nx_emu_s390x.nx itself, which would calibrate the ruler to its subject. SEPARATE ORGAN, NOT A PATCH TO THE INCUMBENT: five other ISA lanes are editing the estate at the same time, and concurrent edits to one file silently clobber each other here. The SHAPE is copied from nx_isa_conform_gate (word emitters, five-way classification, a value-printing report, negative controls, a fixture-reached tooth, a good-when-higher ratchet); nothing is imported from it, so neither can break the other. FIVE OUTCOMES, NEVER ONE: PASS ran and matched the manual-derived expectation WRONG-ANSWER ran to completion and computed the wrong value UNSUPPORTED hit an instruction class the emulator does not implement RAN-OFF-END the interpreter loop ended without an exit syscall FAULT bad pc, out-of-range access, or the step budget Collapsing these into FAIL is what makes a gap unactionable: an unimplemented instruction class and a miscomputed result need OPPOSITE fixes. WHAT MAKES s390x DIFFERENT FROM EVERY OTHER LANE ON THIS BOARD: it is the only VARIABLE-LENGTH ISA here. The instruction length comes from the top two bits of byte 0 (00 -> 2 bytes, 01/10 -> 4, 11 -> 6), so the emitter cannot be a single put_word helper and every branch displacement is a HALFWORD count, not a byte count. A fixture that assumed a fixed width would mis-place every label and the resulting garbage would read as the emulator being incomplete. So there is an explicit tooth asserting the emitter really returns 2, 4 and 6. BIG-ENDIAN. Every field below is written most-significant byte first. Getting this wrong is the silent-fixture defect: the decoder reads garbage, reports UNSUPPORTED, and the FIXTURE's bug wears the emulator's name. THE TWO NEGATIVE CONTROLS THAT ARE NOT DECORATION: nx_emu_s390x used to set its "handled" flag for a whole opcode family BEFORE looking at the extended opcode, so an unimplemented member of that family executed as a silent

dependencies 3 imports · 0 importers

nx_gate_verdict.nx nx_syscalls.nx nx_emu_s390x.nx nx_isa_s390x_gate.nx

imports: nx_gate_verdict.nxnx_syscalls.nxnx_emu_s390x.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main gv_head gv_puts sys_write gv_ctr sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_mmap ↻ gv_puts ↻ sx_nl sys_mmap ↻ sys_write ↻ sx_guest sys_mmap ↻ sx_svc sx_ri sx_ril gv_num sys_mmap ↻ sys_write ↻ sys_munmap gv_check gv_puts ↻ sx_report sx_classify gv_puts ↻ gv_num ↻

structs

none

consts

64const SX_GUEST_BYTES: i64 = 1048576 // 1 MiB guest image
65const SX_ENTRY: i64 = 0 // KAT code is loaded at guest vaddr 0
66const SX_SP: i64 = 983040 // 960 KiB: above the code, inside the image
67const SX_SCRATCH: i64 = 512 // load/store KATs use this guest address
68const SX_MODE_FILE: i64 = 420 // 0644. 420 and 0x1a4 are the SAME constant
75const SX_UNSUPPORTED: i64 = -1
76const SX_RANOFF: i64 = -2
77const SX_FAULT: i64 = -3
80const SX_O_PASS: i64 = 0
81const SX_O_WRONG: i64 = 1
82const SX_O_UNSUP: i64 = 2
83const SX_O_FAULT: i64 = 3
84const SX_O_RANOFF: i64 = 4
87const SX_OP_BCR: i64 = 0x07
88const SX_OP_SVC: i64 = 0x0A
89const SX_OP_RI: i64 = 0xA7
90const SX_OP_RRE: i64 = 0xB9
91const SX_OP_LA: i64 = 0x41
92const SX_OP_RXY: i64 = 0xE3
93const SX_OP_RSY: i64 = 0xEB
94const SX_OP_RIL: i64 = 0xC0
99const SX_RI_BRC: i64 = 0x4
100const SX_RI_BRAS: i64 = 0x5
101const SX_RI_BRCT: i64 = 0x6
102const SX_RI_BRCTG: i64 = 0x7
103const SX_RI_LHI: i64 = 0x8
104const SX_RI_LGHI: i64 = 0x9
105const SX_RI_AHI: i64 = 0xA
106const SX_RI_AGHI: i64 = 0xB
107const SX_RI_MGHI: i64 = 0xD
108const SX_RI_CHI: i64 = 0xE
109const SX_RI_CGHI: i64 = 0xF
112const SX_RRE_LGR: i64 = 0x04
113const SX_RRE_AGR: i64 = 0x08
114const SX_RRE_SGR: i64 = 0x09
115const SX_RRE_MSGR: i64 = 0x0C
116const SX_RRE_CGR: i64 = 0x20
117const SX_RRE_CLGR: i64 = 0x21
118const SX_RRE_NGR: i64 = 0x80
119const SX_RRE_OGR: i64 = 0x81
120const SX_RRE_XGR: i64 = 0x82
123const SX_RRE_LRVGR: i64 = 0x0F
126const SX_RXY_LG: i64 = 0x04
127const SX_RXY_STG: i64 = 0x24
128const SX_RSY_SRAG: i64 = 0x0A
129const SX_RSY_SRLG: i64 = 0x0C
130const SX_RSY_SLLG: i64 = 0x0D
133const SX_RIL_BRCL: i64 = 0x4
134const SX_RIL_BRASL: i64 = 0x5
137const SX_M_ALWAYS: i64 = 15
138const SX_M_EQ: i64 = 8
139const SX_M_NE: i64 = 7
140const SX_M_LOW: i64 = 4
141const SX_M_HIGH: i64 = 2
144const SX_SVC_EXIT: i64 = 1
145const SX_SVC_UNKNOWN: i64 = 99 // deliberately not implemented
148const SX_R0: i64 = 0
149const SX_R2: i64 = 2 // the exit-status register on Linux s390x
150const SX_R3: i64 = 3
151const SX_R4: i64 = 4
152const SX_R5: i64 = 5
153const SX_R14: i64 = 14 // the architected return-address register
157const SX_LEN_RR: i64 = 2
158const SX_LEN_RI: i64 = 4
159const SX_LEN_RIL: i64 = 6
164const SX_NB_BYTES: i64 = 2048
165const SX_NB_OFF: i64 = 0
166const SX_NB_PTR: i64 = 1
167const SX_NB_ROW_MAX: i64 = 256
168const SX_BOX_BYTES: i64 = 32
170const SX_NL: i64 = 10
171const SX_SPACE: i64 = 32
172const SX_DIG_LO: i64 = 48
173const SX_DIG_HI: i64 = 57
174const SX_UNSEEDED: i64 = -1
176const SX_RATCHET: *u8 = "knowledge/status/isa_s390x.ratchet"

functions

180func sx_nl() -> i64
called by 2: sx_reportmain calls 2: sys_mmapsys_write
187func sx_guest() -> *u8 { return sys_mmap(SX_GUEST_BYTES) }
196func sx_rr(c: *u8, off: i64, op: i64, r1: i64, r2: i64) -> i64
203func sx_svc(c: *u8, off: i64, imm: i64) -> i64
210func sx_ri(c: *u8, off: i64, r1: i64, op2: i64, i2: i64) -> i64
219func sx_rre(c: *u8, off: i64, op2: i64, r1: i64, r2: i64) -> i64
228func sx_rx(c: *u8, off: i64, r1: i64, x2: i64, b2: i64, d2: i64) -> i64
called by 1: sx_k_base_zero
237func sx_rxy(c: *u8, off: i64, r1: i64, x2: i64, b2: i64, d2: i64, op2: i64) -> i64
called by 1: sx_k_load_store
248func sx_rsy(c: *u8, off: i64, r1: i64, r3: i64, b2: i64, d2: i64, op2: i64) -> i64
260func sx_ril(c: *u8, off: i64, r1: i64, op2: i64, i2: i64) -> i64
270func sx_run(m: *u8) -> i64 { return emu_s390x_run_mem(m, SX_GUEST_BYTES, SX_ENTRY, SX_SP) }
274func sx_classify(got: i64, want: i64) -> i64
called by 2: sx_reportmain
282func sx_outcome_name(o: i64) -> *u8
called by 2: sx_reportmain
292func sx_report(kat: *u8, got: i64, want: i64, bx: *i64) -> i64
331func sx_k_imm_arith() -> i64
344func sx_k_aghi_opcode() -> i64
called by 1: main calls 4: sx_guestsx_risx_svcsx_run
355func sx_k_sub() -> i64
365func sx_k_mul() -> i64
377func sx_k_logic() -> i64
396func sx_k_branch_loop() -> i64
415func sx_k_brctg_loop() -> i64
called by 1: main calls 4: sx_guestsx_risx_svcsx_run
431func sx_k_load_store() -> i64
446func sx_k_base_zero() -> i64
460func sx_k_shift_logical() -> i64
469func sx_k_shift_arith() -> i64
491func sx_k_ahi_is_32bit() -> i64
510func sx_k_brcl_cond() -> i64
528func sx_k_call_return() -> i64
545func sx_k_bcr_zero_is_nop() -> i64
called by 1: main calls 5: sx_guestsx_risx_rrsx_svcsx_run
564func sx_k_clgr_unsigned() -> i64
587func sx_nc_unimplemented_subopcode() -> i64
598func sx_nc_unknown_svc() -> i64
called by 1: main calls 4: sx_guestsx_risx_svcsx_run
614func sx_match_at(buf: *u8, n: i64, p: i64, s: *u8) -> i64
called by 1: sx_ratchet_read
628func sx_digits_at(buf: *u8, n: i64, p0: i64) -> i64
called by 1: sx_ratchet_read
652func sx_ratchet_read() -> i64
684func sx_ratchet_write(passed: i64) -> i64
701func main(argc: i64, argv: *i64) -> i64