code wiki / (root) / nx_emu_s390x.nx

nx_emu_s390x.nx

buildroot/runtime/nx_emu_s390x.nx

19527 B403 linesdepth 3pulls 3 transitivereach 1 importersview sourcekind librarytopic emu
docsdependenciesstructsconstsfunctions

about

nx_emu_s390x.nx -- sovereign IBM Z (s390x) interpreter (NX-EMU). 64-bit big-endian, 16 GPRs, VARIABLE-LENGTH instructions (length from the top 2 bits of byte0: 00->2, 01/10->4, 11->6). z/Architecture is the only variable length ISA on the estate board, so the fetch width is decoded, never assumed. Linux s390x: svc <imm> = syscall number, args r2.., exit = 1 (code in r2). NO qemu. license_tier: ORIGINAL DECODED TODAY, by family: RR 07 BCR (all 16 masks, and R2=0 is the architected no-operation) RR 0A SVC (1 = exit; every other number is an honest UNSUPPORTED) RI A7 x4 BRC x5 BRAS x6 BRCT x7 BRCTG x8 LHI x9 LGHI xA AHI xB AGHI xD MGHI xE CHI xF CGHI RRE B9 04 LGR 08 AGR 09 SGR 0C MSGR 20 CGR 21 CLGR 80 NGR 81 OGR 82 XGR RX 41 LA RXY E3 04 LG 08 AG 09 SG 24 STG RSY EB 04 LMG 0A SRAG 0C SRLG 0D SLLG 24 STMG RIL C0 x0 LARL x1 LGFI x4 BRCL x5 BRASL SEVEN DEFECTS THIS GENERATION FIXES, each found by reading the z/Architecture Principles of Operation extended-opcode tables rather than the source: 1. AGHI WAS DECODED AT THE WRONG EXTENDED OPCODE. The RI table is A7x8 LHI, A7x9 LGHI, A7xA AHI, A7xB AGHI. The previous generation implemented A7xA as a 64-bit add labelled aghi and had NO A7xB case, so a real AGHI executed as a SILENT NO-OP and a real AHI executed with the wrong width. Both are wrong-answer generators that still run to exit. 2. AN UNKNOWN EXTENDED OPCODE SILENTLY DID NOTHING. handled was set for the whole A7 / B9 / E3 / EB / C0 family before the sub-opcode was examined, so every unimplemented member of those families no-opped and the program ran on with wrong data. That converts UNSUPPORTED into WRONG-ANSWER, which is the one collapse an ISA ruler exists to refuse: a missing instruction and a miscomputed one need OPPOSITE fixes. Each family now carries a subok flag (one per family). 3. THERE WAS NO CONDITION CODE AND NO CONDITIONAL BRANCH AT ALL, so no loop and no if could run. BCR honoured only mask 15. Added: a cc register set by the arithmetic, compare and logic classes, plus BRC, BRCL, BRCT, BRCTG and the full 16-way BCR mask. 4. BASE REGISTER 0 WAS TREATED AS A REAL REGISTER. PoP: a zero in the B or X field means THE ABSENCE OF A BASE, not the contents of general register 0. The old code honoured that for X and not for B, so any program that keeps a live value in r0 addressed the wrong storage.

dependencies 1 imports · 1 importers

nx_syscalls_x86_64.nx nx_emu_s390x.nx nx_isa_s390x_gate.nx

imports: nx_syscalls_x86_64.nx

imported by: nx_isa_s390x_gate.nx

structs

none

consts

62const SZ_GUEST: i64 = 16777216
63const SZ_SYS_EXIT: i64 = 1
68const SZ_UNSUPPORTED: i64 = -1
69const SZ_RANOFF: i64 = -2
70const SZ_FAULT: i64 = -3
72const SZ_STEP_BUDGET: i64 = 5000000
73const SZ_EXIT_MASK: i64 = 255
74const SZ_NREG: i64 = 16
75const SZ_REGBYTES: i64 = 8
76const SZ_MAXILEN: i64 = 6
77const SZ_SHIFT_MASK: i64 = 63
78const SZ_WORD: i64 = 8
83const SZ_LO32: i64 = 4294967295
84const SZ_SIGN32: i64 = 2147483648
85const SZ_2P32: i64 = 4294967296
88const SZ_D20_SIGN: i64 = 524288
89const SZ_D20_MOD: i64 = 1048576
93const SZ_CC_EQ: i64 = 0
94const SZ_CC_LO: i64 = 1
95const SZ_CC_HI: i64 = 2
96const SZ_CC_MASK_TOP: i64 = 8

functions

98func sz_ld(mem: *u8, va: i64, width: i64) -> i64 { var v: i64 = 0; var i: i64 = 0; while i < width { v = (v << 8) | (mem[va + i] & 0xff); i = i + 1 } return v } // big-endian
called by 1: emu_s390x_run_mem
99func sz_st(mem: *u8, va: i64, width: i64, val: i64) -> i64 { var i: i64 = 0; while i < width { mem[va + (width - 1 - i)] = (val >> (i * 8)) & 0xff; i = i + 1 } return 0 }
called by 1: emu_s390x_run_mem
100func sz_sx(v: i64, bits: i64) -> i64 { let m: i64 = 1 << (bits - 1); if (v & m) != 0 { return v - (1 << bits) } return v }
called by 1: emu_s390x_run_mem
104func sz_put32(old: i64, lo: i64) -> i64 { return (old - (old & SZ_LO32)) + (lo & SZ_LO32) }
called by 1: emu_s390x_run_mem
107func sz_s32(v: i64) -> i64
called by 1: emu_s390x_run_mem
115func sz_ltu(a: i64, b: i64) -> i64
called by 1: emu_s390x_run_mem
122func sz_srl(v: i64, n: i64) -> i64
called by 1: emu_s390x_run_mem
129func sz_cc_of(v: i64) -> i64
called by 1: emu_s390x_run_mem
136func sz_cc_cmp(a: i64, b: i64) -> i64
called by 1: emu_s390x_run_mem
145func sz_cc_logic(v: i64) -> i64
called by 1: emu_s390x_run_mem
151func sz_bad(ea: i64, width: i64, mem_size: i64) -> i64
called by 1: emu_s390x_run_mem
157func emu_s390x_run_mem(mem: *u8, mem_size: i64, entry: i64, sp0: i64) -> i64
398func emu_s390x_run(code: *u8, code_len: i64) -> i64