1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
|
/***************************************************************
LIBMCPU.H
This file contains public MCPU operation functions & data
declarations.
PART OF : MCPU - library .
Copyright (C) 2026 by Andrew V.Kosteltsev.
All Rights Reserved.
***************************************************************/
#ifndef __LIB_MCPU_H
#define __LIB_MCPU_H
#ifdef __cplusplus
extern "C" {
#endif
#include <libmpu.h>
#define CPU_REGISTERS_MEM_SIZE_IN_UNITS 524288
#define CPU_REGISTER_ADDRESS_MAX 0x0007ffffU
#define CPU_REGISTER_MIN_BITS 8U
#define CPU_REGISTER_MAX_BITS 65536U
/* LibCPU CALL ABI return-value area at the top of the register file. */
#define CPU_RETURN_AREA_SIZE 0x00002000U
#define CPU_RETURN_AREA_BEGIN 0x0007e000U
#define CPU_RETURN_AREA_END 0x00080000U
/* MCPU SYSCALL register ABI. */
#define CPU_SYSCALL_NARGS_ADDR 0x0007fff8U
#define CPU_SYSCALL_SYSNO_ADDR 0x0007fffcU
#define CPU_SYSCALL_RET_ADDR 0x0007fff8U
#define CPU_SYSCALL_ARG0_ADDR 0x0007fff0U
#define CPU_SYSCALL_ARG1_ADDR 0x0007ffe8U
#define CPU_SYSCALL_ARG2_ADDR 0x0007ffe0U
#define CPU_SYSCALL_ARG3_ADDR 0x0007ffd8U
#define CPU_SYSCALL_ARG4_ADDR 0x0007ffd0U
#define CPU_SYSCALL_ARG5_ADDR 0x0007ffc8U
#define CPU_SYSCALL_MAX_ARGS 6U
/* Machine encoding sizes. */
#define CPU_OPCODE_SIZE 2U
#define CPU_REG24_SIZE 3U
#define CPU_IMM64_SIZE 8U
#define CPU_ADDR64_SIZE 8U
#define CPU_CODE64_SIZE 8U
#define CPU_OFF64_SIZE 8U
#define CPU_CONST8_SIZE 1U
#define CPU_PSWBIT8_SIZE 1U
#define CPU_PTR64_SIZE 8U
/*
* Byte-order domains.
*
* PROGRAM multi-byte machine fields are always canonical MSB-first.
* Architectural data objects (register file, DATA, STACK and future data
* segments) use the target data representation selected by LibMPU.
* CPU_DATA_* aliases make this ABI dependency explicit to LibCPU tools.
*/
#define CPU_CODE_BYTE_ORDER_MSB_FIRST 1
#define CPU_DATA_BYTE_ORDER MPU_BYTE_ORDER
#define CPU_DATA_BYTE_ORDER_BIG_ENDIAN MPU_BYTE_ORDER_BIG_ENDIAN
#define CPU_DATA_BYTE_ORDER_LITTLE_ENDIAN MPU_BYTE_ORDER_LITTLE_ENDIAN
#define CPU_DATA_WORD_ORDER MPU_WORD_ORDER
#define CPU_DATA_WORD_ORDER_BIG_ENDIAN MPU_WORD_ORDER_BIG_ENDIAN
#define CPU_DATA_WORD_ORDER_LITTLE_ENDIAN MPU_WORD_ORDER_LITTLE_ENDIAN
extern __mpu_uint16_t __cpu_data_get_u16( const __mpu_UNIT_t *p );
extern __mpu_uint32_t __cpu_data_get_u32( const __mpu_UNIT_t *p );
extern __mpu_uint64_t __cpu_data_get_u64( const __mpu_UNIT_t *p );
extern void __cpu_data_put_u16( __mpu_UNIT_t *p, __mpu_uint16_t v );
extern void __cpu_data_put_u32( __mpu_UNIT_t *p, __mpu_uint32_t v );
extern void __cpu_data_put_u64( __mpu_UNIT_t *p, __mpu_uint64_t v );
extern __mpu_uint16_t __cpu_code_get_u16( const __mpu_UNIT_t *p );
extern __mpu_uint32_t __cpu_code_get_u32( const __mpu_UNIT_t *p );
extern __mpu_uint64_t __cpu_code_get_u64( const __mpu_UNIT_t *p );
extern void __cpu_code_put_u16( __mpu_UNIT_t *p, __mpu_uint16_t v );
extern void __cpu_code_put_u32( __mpu_UNIT_t *p, __mpu_uint32_t v );
extern void __cpu_code_put_u64( __mpu_UNIT_t *p, __mpu_uint64_t v );
/* Fixed CALL ABI bases. Individual argument offsets are computed inside
the aligned argument block and are therefore not generally fixed. */
#define CPU_CALL_RETURN_PC_SIZE CPU_CODE64_SIZE
#define CPU_ABI_CALLEE_ARGUMENT_BLOCK_OFFSET 8U
#define CPU_ABI_FP_ARGUMENT_BLOCK_OFFSET 16U
#define CPU_ABI_HIDDEN_RESULT_BLOCK_OFFSET 0U
/* LibCPU C-like ABI/data-layout conventions used by assembler/linker code. */
#define CPU_ABI_MAX_ALIGN 16U
#define CPU_ABI_STACK_ALIGN 16U
#define CPU_ABI_STACK_RED_ZONE_SIZE 0U
#define CPU_ABI_ARGUMENT_BLOCK_ALIGN 16U
#define CPU_DATA_NULL_GUARD_SIZE 16U
#define CPU_HEAP_GUARD_SIZE 16U
#define CPU_HEAP_BEGIN CPU_HEAP_GUARD_SIZE
#define CPU_NULL_PTR __mpu_UINT64_C( 0x0000000000000000 )
/***************************************************************
PTR64 - segmented virtual pointer.
bits 63..60 : 4-bit segment selector
bits 59..0 : byte offset inside the selected segment
A PTR64 is an architectural value, never a host pointer. The
60-bit offset gives each segment a 2^60-byte (1 EiB) virtual
address span. Segment identifiers 0x3..0x7 are assigned to model/runtime data
address spaces. Selectors 0x8..0xf remain reserved.
***************************************************************/
#define CPU_PTR_SEG_SHIFT 60U
#define CPU_PTR_SEG_MASK __mpu_UINT64_C( 0xf000000000000000 )
#define CPU_PTR_OFFSET_MASK __mpu_UINT64_C( 0x0fffffffffffffff )
typedef enum __cpu_ptr_segment
{
CPU_PTR_SEG_DATA = 0x0,
CPU_PTR_SEG_STACK = 0x1,
CPU_PTR_SEG_PROGRAM = 0x2,
CPU_PTR_SEG_CONTROL = 0x3,
CPU_PTR_SEG_INPUT = 0x4,
CPU_PTR_SEG_OUTPUT = 0x5,
CPU_PTR_SEG_TRACE = 0x6,
CPU_PTR_SEG_HEAP = 0x7
} cpu_ptr_segment;
#define CPU_PTR_SEG_FIRST_RESERVED 0x8U
#define CPU_PTR_SEG_MAX 0x0fU
/* CONTROL and INPUT are guest read-only. OUTPUT, TRACE and HEAP are guest
read/write. PROGRAM is guest read-only. DATA and STACK remain guest
read/write. Reserved PTR64 selectors remain structurally valid pointer
values; non-dereferencing pointer arithmetic may preserve them, but any
operation requiring address-space meaning faults until a selector is
architecturally assigned. */
extern int __cpu_ptr_make ( __mpu_uint64_t *ptr,
unsigned int segment,
__mpu_uint64_t offset );
extern unsigned int __cpu_ptr_segment( __mpu_uint64_t ptr );
extern __mpu_uint64_t __cpu_ptr_offset ( __mpu_uint64_t ptr );
/***************************************************************
PROGRAM STATUS WORD.
***************************************************************/
#define PSW_AF_MASK __mpu_UINT32_C( 0x00000001 )
#define PSW_CF_MASK __mpu_UINT32_C( 0x00000002 )
#define PSW_OF_MASK __mpu_UINT32_C( 0x00000004 )
#define PSW_SF_MASK __mpu_UINT32_C( 0x00000008 )
#define PSW_PF_MASK __mpu_UINT32_C( 0x00000010 )
#define PSW_ZF_MASK __mpu_UINT32_C( 0x00000020 )
#define PSW_RF_MASK __mpu_UINT32_C( 0x00000040 )
#define PSW_VF_MASK __mpu_UINT32_C( 0x00000080 )
#define PSW_DOMF_MASK __mpu_UINT32_C( 0x00000100 )
#define PSW_SNGF_MASK __mpu_UINT32_C( 0x00000200 )
#define PSW_OVFF_MASK __mpu_UINT32_C( 0x00000400 )
#define PSW_UDFF_MASK __mpu_UINT32_C( 0x00000800 )
#define PSW_TLSF_MASK __mpu_UINT32_C( 0x00001000 )
#define PSW_PLSF_MASK __mpu_UINT32_C( 0x00002000 )
#define PSW_INDF_MASK __mpu_UINT32_C( 0x00004000 )
#define PSW_INXF_MASK __mpu_UINT32_C( 0x00008000 )
#define PSW_HF_MASK __mpu_UINT32_C( 0x00010000 )
#define PSW_TF_MASK __mpu_UINT32_C( 0x00020000 )
#define PSW_IF_MASK __mpu_UINT32_C( 0x00040000 )
#define PSW_MODE_MASK __mpu_UINT32_C( 0x00180000 )
/* Architectural arithmetic/status partition. The lower byte is the CPU
flag domain and the upper byte is the MPU mathematical flag domain. The
implementation-level PSW_MPU_MASK name is retained for the full LibMPU-backed
PSW[15:0] facade used by existing arithmetic primitives. */
#define PSW_CPUF_MASK __mpu_UINT32_C( 0x000000ff )
#define PSW_MPUF_MASK __mpu_UINT32_C( 0x0000ff00 )
#define PSW_MPU_MASK __mpu_UINT32_C( 0x0000ffff )
#define PSW_CPU_MASK __mpu_UINT32_C( 0x001f0000 )
#define PSW_USED_MASK __mpu_UINT32_C( 0x001fffff )
#define PSW_HF_SHIFT 16
#define PSW_TF_SHIFT 17
#define PSW_IF_SHIFT 18
#define PSW_MODE_SHIFT 19
/*
* Normal-function PSW calling convention.
*
* CALL/CALLP/RET themselves are PSW-neutral: they do not save, restore or
* modify PSW. The masks below describe the ABI contract across a normal
* function call.
*
* PSW[15:0] is the arithmetic/status domain and is caller-clobbered.
* PSW[7:0] is the CPU flag byte; PSW[15:8] is the MPU mathematical flag byte.
* TF, IF and MODE are persistent control state; a callee that changes any of
* them must restore the incoming value before an ordinary RET.
* HF is execution state, not a caller/callee-saved function value: HALT ends
* normal control flow, while CALL/CALLP/RET themselves leave HF unchanged.
*/
#define CPU_PSW_ABI_VOLATILE_STATUS_MASK PSW_MPU_MASK
#define CPU_PSW_ABI_PERSISTENT_CONTROL_MASK \
(PSW_TF_MASK | PSW_IF_MASK | PSW_MODE_MASK)
#define CPU_PSW_ABI_EXECUTION_STATE_MASK PSW_HF_MASK
extern void __cpu_init( void );
extern void __cpu_free_context( void );
extern __mpu_uint64_t *__ptr_cpu_pc( void );
extern __mpu_uint64_t *__ptr_cpu_sp( void );
extern __mpu_uint64_t *__ptr_cpu_fp( void );
extern __mpu_UNIT_t *__ptr_cpu_registers( void );
#define __cpu_pc (*__ptr_cpu_pc())
#define __cpu_sp (*__ptr_cpu_sp())
#define __cpu_fp (*__ptr_cpu_fp())
#define __cpu_registers (__ptr_cpu_registers())
/***************************************************************
PHYSICAL REGISTER VIEWS.
REG24 machine encoding:
bits 23..20 : WIDTH code, 0..13 => 8..65536 bits
bits 19..0 : byte address; bit 19 is MBZ for the current
512 KiB register file.
Source assembler uses r<bits>@addr for integer/real views and
c<bits>@addr for complex views. In both forms <bits> is the
PHYSICAL register width. A c64 view therefore contains two
real32 components and has exactly the same REG24 encoding as
r64 at the same address.
***************************************************************/
typedef struct __cpu_register cpu_register;
struct __cpu_register
{
unsigned int bits;
__mpu_uint32_t address;
};
extern __mpu_size_t __cpu_reg_size ( unsigned int bits );
extern int __cpu_reg_valid( unsigned int bits, __mpu_uint32_t address );
extern __mpu_UNIT_t *__cpu_reg_ptr ( unsigned int bits, __mpu_uint32_t address );
/* Canonical ABI return register: addr = 0x80000 - physical_size. */
extern int __cpu_return_reg ( cpu_register *reg, unsigned int bits );
extern int __cpu_encode_reg24( __mpu_UNIT_t out[CPU_REG24_SIZE],
const cpu_register *reg );
extern int __cpu_decode_reg24( cpu_register *reg,
const __mpu_UNIT_t in[CPU_REG24_SIZE] );
/***************************************************************
PSW access.
***************************************************************/
extern __mpu_uint32_t __cpu_get_psw ( void );
extern void __cpu_set_psw ( __mpu_uint32_t psw );
extern void __cpu_clear_psw ( void );
extern int __cpu_gth ( void );
extern int __cpu_gtt ( void );
extern int __cpu_gti ( void );
extern void __cpu_sth ( void );
extern void __cpu_stt ( void );
extern void __cpu_sti ( void );
extern void __cpu_clh ( void );
extern void __cpu_clt ( void );
extern void __cpu_cli ( void );
extern void __cpu_cmh ( void );
extern void __cpu_cmt ( void );
extern void __cpu_cmi ( void );
extern int __cpu_gtmode ( void );
extern int __cpu_stmode ( unsigned int mode );
/***************************************************************
ARCHITECTURAL MEMORY SPACES.
PROGRAM, DATA, STACK, CONTROL, INPUT, OUTPUT, TRACE and HEAP are
independent byte-addressable guest spaces backed by anonymous
mmap() mappings. Architectural bounds always use segment size,
never host page-rounded capacity. No guest segment is file-backed.
PROGRAM is host-protected read-only after loading. CONTROL and
INPUT remain host-writable so a runtime/supervisor can update them,
but guest STOREP/BMOV destinations to those spaces fault. OUTPUT,
TRACE and HEAP are guest read/write.
STACK grows toward lower addresses; an empty allocated stack has
SP == FP == stack_size.
HEAP is zero-filled runtime storage and has no assembler payload.
Offsets [0,CPU_HEAP_BEGIN) are reserved. The current API records
initial architectural size and a maximum limit. malloc/free are
library concerns; dynamic heap growth is intentionally reserved for
a future runtime/system-call ABI.
***************************************************************/
extern int __cpu_program_alloc ( __mpu_uint64_t size );
extern void __cpu_program_free ( void );
extern int __cpu_program_protect ( void );
extern __mpu_UNIT_t *__cpu_program_ptr ( void );
extern __mpu_uint64_t __cpu_program_size ( void );
extern int __cpu_program_set ( const __mpu_UNIT_t *data,
__mpu_uint64_t size );
extern int __cpu_data_alloc ( __mpu_uint64_t size );
extern void __cpu_data_free ( void );
extern __mpu_UNIT_t *__cpu_data_ptr ( void );
extern __mpu_uint64_t __cpu_data_size ( void );
extern int __cpu_data_set ( const __mpu_UNIT_t *data,
__mpu_uint64_t size );
extern int __cpu_stack_alloc ( __mpu_uint64_t size );
extern void __cpu_stack_free ( void );
extern __mpu_UNIT_t *__cpu_stack_ptr ( void );
extern __mpu_uint64_t __cpu_stack_size ( void );
extern int __cpu_control_alloc ( __mpu_uint64_t size );
extern void __cpu_control_free ( void );
extern __mpu_UNIT_t *__cpu_control_ptr ( void );
extern __mpu_uint64_t __cpu_control_size ( void );
extern int __cpu_control_set ( const __mpu_UNIT_t *data, __mpu_uint64_t size );
extern int __cpu_input_alloc ( __mpu_uint64_t size );
extern void __cpu_input_free ( void );
extern __mpu_UNIT_t *__cpu_input_ptr ( void );
extern __mpu_uint64_t __cpu_input_size ( void );
extern int __cpu_input_set ( const __mpu_UNIT_t *data, __mpu_uint64_t size );
extern int __cpu_output_alloc ( __mpu_uint64_t size );
extern void __cpu_output_free ( void );
extern __mpu_UNIT_t *__cpu_output_ptr ( void );
extern __mpu_uint64_t __cpu_output_size ( void );
extern int __cpu_output_set ( const __mpu_UNIT_t *data, __mpu_uint64_t size );
extern int __cpu_trace_alloc ( __mpu_uint64_t size );
extern void __cpu_trace_free ( void );
extern __mpu_UNIT_t *__cpu_trace_ptr ( void );
extern __mpu_uint64_t __cpu_trace_size ( void );
extern int __cpu_trace_set ( const __mpu_UNIT_t *data, __mpu_uint64_t size );
extern int __cpu_heap_alloc ( __mpu_uint64_t initial_size, __mpu_uint64_t maximum_size );
extern void __cpu_heap_free ( void );
extern __mpu_UNIT_t *__cpu_heap_ptr ( void );
extern __mpu_uint64_t __cpu_heap_size ( void );
extern __mpu_uint64_t __cpu_heap_limit ( void );
/***************************************************************
MACHINE OPCODES.
The opcode completely determines the number and kind of all
following operands. Multi-byte machine fields use canonical
MSB-first byte order.
***************************************************************/
typedef enum __cpu_opcode
{
CPU_OP_NOP = 0x0000,
CPU_OP_HALT = 0x0001,
CPU_OP_END = 0x0002, /* end current externally managed execution phase */
CPU_OP_EXIT = 0x0003, /* r32 signed program/model exit status */
CPU_OP_SYSCALL = 0x0004, /* system call through fixed register ABI */
CPU_OP_SETF = 0x0010, /* set one writable PSW[15:0] flag */
CPU_OP_CLRF = 0x0011, /* clear one writable PSW[15:0] flag */
CPU_OP_CLRCPUF = 0x0012, /* clear CPU flag byte PSW[7:0] */
CPU_OP_CLRMPUF = 0x0013, /* clear MPU flag byte PSW[15:8] */
CPU_OP_MOV = 0x0100,
CPU_OP_CLR = 0x0101,
CPU_OP_SWAP = 0x0102,
CPU_OP_BSWAP = 0x0103, /* raw byte reversal: Rdst, Rsrc */
CPU_OP_LDI = 0x0110, /* R, signed integer64 immediate */
CPU_OP_LDR = 0x0111, /* R, IEEE binary64 immediate */
CPU_OP_LDC = 0x0112, /* R, 2 x IEEE binary32 */
CPU_OP_LOAD = 0x0120, /* R, DATA ADDR64 */
CPU_OP_STORE = 0x0121, /* DATA ADDR64, R */
CPU_OP_LEA = 0x0130, /* r64, PTR64 immediate */
CPU_OP_LEASP = 0x0131, /* r64, signed OFF64 -> PTR64 */
CPU_OP_LOADP = 0x0132, /* R/C, r64(PTR64) */
CPU_OP_STOREP = 0x0133, /* r64(PTR64), R/C */
CPU_OP_PADD = 0x0140, /* r64 = PTR64 + signed r64 */
CPU_OP_PADDI = 0x0141, /* r64 = PTR64 + signed OFF64 */
CPU_OP_PSUB = 0x0142, /* r64 = PTR64 - signed r64 */
CPU_OP_PSUBI = 0x0143, /* r64 = PTR64 - signed OFF64 */
CPU_OP_PDIFF = 0x0144, /* r64 = PTR64 - PTR64 bytes */
CPU_OP_BMOV = 0x0150, /* PTR64 dst, PTR64 src, r64 byte count */
CPU_OP_BMOVI = 0x0151, /* PTR64 dst, PTR64 src, IMM64 byte count */
CPU_OP_IADD = 0x1000,
CPU_OP_IADC = 0x1001,
CPU_OP_ISUB = 0x1002,
CPU_OP_ISBB = 0x1003,
CPU_OP_IAND = 0x1004,
CPU_OP_IOR = 0x1005,
CPU_OP_IXOR = 0x1006,
CPU_OP_INOT = 0x1010,
CPU_OP_INEG = 0x1011,
CPU_OP_ICMP = 0x1020,
CPU_OP_ITEST = 0x1021,
CPU_OP_ISHL = 0x1030, /* logical shift left by one bit */
CPU_OP_ISHR = 0x1031, /* logical shift right by one bit */
CPU_OP_ISAL = 0x1032, /* arithmetic shift left by one bit */
CPU_OP_ISAR = 0x1033, /* arithmetic shift right by one bit */
CPU_OP_IROL = 0x1034, /* rotate left by one bit */
CPU_OP_IROR = 0x1035, /* rotate right by one bit */
CPU_OP_IRCL = 0x1036, /* rotate left through CF by one bit */
CPU_OP_IRCR = 0x1037, /* rotate right through CF by one bit */
CPU_OP_ISHLN = 0x1040, /* Rdst,Rsrc,r64 count */
CPU_OP_ISHRN = 0x1041,
CPU_OP_ISALN = 0x1042,
CPU_OP_ISARN = 0x1043,
CPU_OP_IROLN = 0x1044,
CPU_OP_IRORN = 0x1045,
CPU_OP_IRCLN = 0x1046,
CPU_OP_IRCRN = 0x1047,
CPU_OP_IINC = 0x1050,
CPU_OP_IDEC = 0x1051,
CPU_OP_IXCHG = 0x1052,
CPU_OP_ICPY = 0x1053, /* width-changing unsigned copy */
CPU_OP_ICVT = 0x1054, /* width-changing signed conversion */
CPU_OP_IMUL = 0x1060, /* unsigned full product */
CPU_OP_ISMUL = 0x1061, /* signed full product */
CPU_OP_IDIV = 0x1062, /* quot,rem,num,den (unsigned) */
CPU_OP_ISDIV = 0x1063, /* quot,rem,num,den (signed) */
CPU_OP_IBITSLEN = 0x1064, /* r64 result, integer source */
CPU_OP_RADD = 0x2000,
CPU_OP_RSUB = 0x2001,
CPU_OP_RMUL = 0x2002,
CPU_OP_RDIV = 0x2003,
CPU_OP_RSQRT = 0x2010,
CPU_OP_RSIN = 0x2020,
CPU_OP_RCOS = 0x2021,
CPU_OP_RTAN = 0x2022,
CPU_OP_RASIN = 0x2023,
CPU_OP_RACOS = 0x2024,
CPU_OP_RATAN = 0x2025,
CPU_OP_RLOG = 0x2030,
CPU_OP_RLOG10 = 0x2031,
CPU_OP_RLOG2 = 0x2032,
CPU_OP_REXP = 0x2033,
CPU_OP_RSINH = 0x2040,
CPU_OP_RCOSH = 0x2041,
CPU_OP_RTANH = 0x2042,
CPU_OP_RPOW = 0x2050,
CPU_OP_RHYPOT = 0x2051,
CPU_OP_RATAN2 = 0x2052,
CPU_OP_RNEG = 0x2060,
CPU_OP_RABS = 0x2061,
CPU_OP_RCMP = 0x2062, /* r64 result {-2,-1,0,+1}, Ra, Rb */
CPU_OP_RCPY = 0x2063,
CPU_OP_RCVT = 0x2064,
CPU_OP_RFLOOR = 0x2070,
CPU_OP_RCEIL = 0x2071,
CPU_OP_RROUND = 0x2072,
CPU_OP_RFREXP = 0x2073, /* R significand, I exponent, R source */
CPU_OP_RLDEXP = 0x2074, /* R dst, R src, I exponent */
CPU_OP_RLOGB = 0x2075, /* I dst, R src */
CPU_OP_RMODF = 0x2076, /* R frac, R integer, R source */
CPU_OP_RREMAIN = 0x2077,
CPU_OP_RLOG1P = 0x2080,
CPU_OP_REXPM1 = 0x2081,
CPU_OP_RASINH = 0x2082,
CPU_OP_RACOSH = 0x2083,
CPU_OP_RATANH = 0x2084,
CPU_OP_ITOR = 0x2090, /* signed integer -> real */
CPU_OP_UITOR = 0x2091, /* unsigned integer -> real */
CPU_OP_RTOI = 0x2092, /* I dst, R frac, R src */
CPU_OP_RTOUI = 0x2093, /* UI dst, R frac, R src */
CPU_OP_RISNEG = 0x20a0, /* r64 predicate, R src */
CPU_OP_RSIGN = 0x20a1, /* r64 signed {-3..+1}, R src */
CPU_OP_RISIND = 0x20a2,
CPU_OP_RISNAN = 0x20a3,
CPU_OP_RISNANMAX = 0x20a4,
CPU_OP_RISNANMIN = 0x20a5,
CPU_OP_RISINF = 0x20a6,
CPU_OP_RISSIGNULL = 0x20a7,
CPU_OP_RCONST = 0x2100, /* R, CONST8 */
CPU_OP_CADD = 0x3000,
CPU_OP_CSUB = 0x3001,
CPU_OP_CMUL = 0x3002,
CPU_OP_CDIV = 0x3003,
CPU_OP_CEXP = 0x3020,
CPU_OP_CSIN = 0x3021,
CPU_OP_CCOS = 0x3022,
CPU_OP_CSINH = 0x3023,
CPU_OP_CCOSH = 0x3024,
CPU_OP_CLOG = 0x3025,
CPU_OP_CSQRT = 0x3026,
CPU_OP_CPOW = 0x3050,
CPU_OP_CREAL = 0x3060, /* R component dst, C src */
CPU_OP_CIMAG = 0x3061, /* R component dst, C src */
CPU_OP_CRTOC = 0x3062, /* C dst, R src */
CPU_OP_CGEN = 0x3063, /* C dst, R real, R imaginary */
CPU_OP_CPOLAR = 0x3064, /* C dst, R rho, R theta */
CPU_OP_CCONJ = 0x3065,
CPU_OP_CABS = 0x3066, /* R dst, C src */
CPU_OP_CNORM = 0x3067, /* R dst, C src */
CPU_OP_CARG = 0x3068, /* R dst, C src */
CPU_OP_CISEQ = 0x3070, /* r64 predicate, C a, C b */
CPU_OP_CISNE = 0x3071,
CPU_OP_CCPY = 0x3072,
CPU_OP_CCVT = 0x3073,
CPU_OP_JMP = 0x4000, /* CODE64 */
CPU_OP_JSET = 0x4001, /* PSWBIT8, CODE64 */
CPU_OP_JCLR = 0x4002, /* PSWBIT8, CODE64 */
CPU_OP_JMPP = 0x4003, /* r64(PROGRAM PTR64) */
CPU_OP_CALL = 0x4010, /* CODE64; push next PC */
CPU_OP_RET = 0x4011, /* pop PC from STACK */
CPU_OP_CALLP = 0x4012, /* r64(PROGRAM PTR64); push next PC */
CPU_OP_PUSH = 0x5000, /* R/C */
CPU_OP_POP = 0x5001, /* R/C */
CPU_OP_LDSP = 0x5010, /* R/C, signed OFF64 */
CPU_OP_STSP = 0x5011, /* signed OFF64, R/C */
CPU_OP_ADJSP = 0x5020, /* signed OFF64 */
CPU_OP_PUSHFP = 0x5030, /* push current 64-bit FP on STACK */
CPU_OP_SETFP = 0x5031, /* FP = SP */
CPU_OP_RESTSP = 0x5032, /* SP = FP */
CPU_OP_POPFP = 0x5033, /* pop 64-bit FP from STACK */
CPU_OP_LDFP = 0x5040, /* R/C, signed OFF64 relative to FP */
CPU_OP_STFP = 0x5041, /* signed OFF64 relative to FP, R/C */
CPU_OP_LEAFP = 0x5042, /* r64, signed OFF64 -> STACK PTR64 */
CPU_OP_SETSP = 0x5050 /* r64(STACK PTR64) -> SP */
} cpu_opcode;
/***************************************************************
PSW bit selectors used by JSET/JCLR and by writable-flag
instructions where explicitly permitted.
MODE is a multi-bit field and is intentionally not
addressable through JSET/JCLR. Branch selectors cover
individual bits 0..18. SETF/CLRF are restricted to bits
0..15 by CPU_PSWBIT_WRITE_MAX.
***************************************************************/
typedef enum __cpu_psw_bit
{
CPU_PSWBIT_AF = 0,
CPU_PSWBIT_CF = 1,
CPU_PSWBIT_OF = 2,
CPU_PSWBIT_SF = 3,
CPU_PSWBIT_PF = 4,
CPU_PSWBIT_ZF = 5,
CPU_PSWBIT_RF = 6,
CPU_PSWBIT_VF = 7,
CPU_PSWBIT_DOMF = 8,
CPU_PSWBIT_SNGF = 9,
CPU_PSWBIT_OVFF = 10,
CPU_PSWBIT_UDFF = 11,
CPU_PSWBIT_TLSF = 12,
CPU_PSWBIT_PLSF = 13,
CPU_PSWBIT_INDF = 14,
CPU_PSWBIT_INXF = 15,
CPU_PSWBIT_HF = 16,
CPU_PSWBIT_TF = 17,
CPU_PSWBIT_IF = 18
} cpu_psw_bit;
#define CPU_PSWBIT_MAX CPU_PSWBIT_IF
#define CPU_PSWBIT_WRITE_MAX CPU_PSWBIT_INXF
/***************************************************************
Predefined real mathematical constants for RCONST.
***************************************************************/
typedef enum __cpu_real_constant
{
CPU_RCONST_ZERO = 0x00,
CPU_RCONST_HALF,
CPU_RCONST_ONE,
CPU_RCONST_TWO,
CPU_RCONST_TEN,
CPU_RCONST_MTEN,
CPU_RCONST_32,
CPU_RCONST_PI = 0x10,
CPU_RCONST_E,
CPU_RCONST_1_LN2,
CPU_RCONST_LN2,
CPU_RCONST_1_LN10,
CPU_RCONST_LN10,
CPU_RCONST_1_LG2,
CPU_RCONST_LG2,
CPU_RCONST_PI_2 = 0x20,
CPU_RCONST_PI_3,
CPU_RCONST_PI_4,
CPU_RCONST_PI_5,
CPU_RCONST_PI_6,
CPU_RCONST_1_PI,
CPU_RCONST_2_PI,
CPU_RCONST_3_PI,
CPU_RCONST_4_PI,
CPU_RCONST_5_PI,
CPU_RCONST_2PI,
CPU_RCONST_3PI,
CPU_RCONST_1_2PI,
CPU_RCONST_1_3PI,
CPU_RCONST_1_4PI,
CPU_RCONST_1_5PI,
CPU_RCONST_1_6PI,
CPU_RCONST_3PI_4,
CPU_RCONST_SQRTPI = 0x40,
CPU_RCONST_1_SQRTPI,
CPU_RCONST_2_SQRTPI,
CPU_RCONST_SQRT2,
CPU_RCONST_1_SQRT2,
CPU_RCONST_SQRT3,
CPU_RCONST_1_SQRT3,
CPU_RCONST_DEGREE,
CPU_RCONST_1_DEGREE,
CPU_RCONST_GOLDENRATIO,
CPU_RCONST_EULERGAMMA,
CPU_RCONST_CATALAN,
CPU_RCONST_EPSILON = 0x50,
CPU_RCONST_IND,
CPU_RCONST_PNAN,
CPU_RCONST_NNAN,
CPU_RCONST_PNANMAX,
CPU_RCONST_NNANMAX,
CPU_RCONST_PNANMIN,
CPU_RCONST_NNANMIN,
CPU_RCONST_PINF,
CPU_RCONST_NINF,
CPU_RCONST_PREALMIN,
CPU_RCONST_NREALMIN,
CPU_RCONST_PREALMAX,
CPU_RCONST_NREALMAX,
CPU_RCONST_PZERO,
CPU_RCONST_NZERO
} cpu_real_constant;
/***************************************************************
DECODED INSTRUCTION REPRESENTATION.
***************************************************************/
typedef enum __cpu_operand_type
{
CPU_OPERAND_NONE = 0,
CPU_OPERAND_REGISTER,
CPU_OPERAND_IMM64,
CPU_OPERAND_ADDR64,
CPU_OPERAND_CODE64,
CPU_OPERAND_OFF64,
CPU_OPERAND_CONST8,
CPU_OPERAND_PSWBIT8,
CPU_OPERAND_PTR64
} cpu_operand_type;
#define CPU_OPERAND_IMMEDIATE CPU_OPERAND_IMM64
typedef struct __cpu_operand cpu_operand;
struct __cpu_operand
{
cpu_operand_type type;
union
{
cpu_register reg;
__mpu_uint64_t imm64;
__mpu_uint64_t addr64;
__mpu_uint64_t code64;
__mpu_int64_t off64;
__mpu_uint8_t const8;
__mpu_uint8_t pswbit8;
__mpu_uint64_t ptr64;
} value;
};
#define CPU_INSTRUCTION_MAX_OPERANDS 4
typedef struct __cpu_instruction cpu_instruction;
struct __cpu_instruction
{
cpu_opcode opcode;
cpu_operand operand[CPU_INSTRUCTION_MAX_OPERANDS];
__mpu_uint64_t length;
};
#define CPU_EXEC_SUCCESS 0
#define CPU_EXEC_INSTRUCTION_FAULT -1
#define CPU_EXEC_OPCODE_FAULT -2
#define CPU_EXEC_OPERAND_FAULT -3
#define CPU_EXEC_REGISTER_FAULT -4
#define CPU_EXEC_WIDTH_FAULT -5
#define CPU_EXEC_MEMORY_FAULT -6
#define CPU_EXEC_DECODE_FAULT -7
#define CPU_EXEC_STACK_FAULT -8
#define CPU_EXEC_POINTER_FAULT -9
#define CPU_EXEC_HALT 1
#define CPU_EXEC_BRANCH 2
#define CPU_EXEC_END 3
#define CPU_EXEC_EXIT 4
typedef enum __cpu_stop_reason
{
CPU_STOP_NONE = 0,
CPU_STOP_END,
CPU_STOP_EXIT,
CPU_STOP_HALT,
CPU_STOP_TRAP,
CPU_STOP_FAULT,
CPU_STOP_KILLED
} cpu_stop_reason;
extern cpu_stop_reason __cpu_get_stop_reason( void );
extern __mpu_int32_t __cpu_get_exit_status( void );
extern void __cpu_clear_stop_reason( void );
extern int __cpu_exec ( const cpu_instruction *instruction );
extern int __cpu_decode_at( const __mpu_UNIT_t *program,
__mpu_uint64_t program_size,
__mpu_uint64_t pc,
cpu_instruction *instruction );
extern int __cpu_decode ( cpu_instruction *instruction );
extern int __cpu_step ( void );
extern int __cpu_run ( void );
#ifdef __cplusplus
} /* ... extern "C" */
#endif
#endif /* __LIB_MCPU_H */
|