LEGアーキテクチャ
Turing Completeの中で作成するふたつめのCPUのアーキテクチャ。
命令セット
4バイトで1命令。1バイト目はopcode、2バイト目はarg1のアドレス、3バイト目はarg2のアドレス、4バイト目はresult保存先のアドレス。
opcode, arg1_address, arg2_address, result_address
また、Conndition系の命令の場合は4バイト目はjump_addressとなる。
opcode, arg1_address, arg2_address, jump_address
Opcode (calc)
000 000: ADD
000 001: SUB
000 010: AND
000 011: OR
000 100: NOT (ignore arg2)
000 101: XOR
000 110: SHL
000 111: SHR
また、Opcodeの8バイト目が1の場合は arg1_address(命令の2バイト目) が arg1の即値(Immediate)となり、7バイト目が1の場合はarg2_address(命令の3バイト目)がarg2の即値となる。
Opcode(cond)
100 000: ==
100 001: !=
100 010: <
100 011: <=
100 100: >
100 101: >=
Opcode(memory)
010 000(16): sw
M[r1+r2] = r3
opcode, r1, r2, r3
r1: RAMアドレス
r2: アドレスオフセット
r3: 書き込むデータを保持するレジスタ
010 001(17): lw
r3 = M[r1+r2]
opcode, r1, r2, r3
r1: RAMアドレス
r2: アドレスオフセット
r3: データをロードするレジスタ
Opcode(function)
00 001 000 (8): call
call sp sp_offset function_label
spはスタックポインタ
M[sp + sp_offset] = counter + 4
sp = sp + 1
jump function_label
(※)現状での実装はcallを呼ぶたびにr5がインクリメントされるため、実質spはr5固定となっている
00 001 001 (9): ret
ret sp sp_offset 0
counter = M[sp + sp_offset]
sp = sp - 1
(※)現状での実装はretを呼ぶたびにr5がデクリメントされるため、実質spはr5固定となっている
Address
000: R0
001: R1
010: R2
011: R3
100: R4
101: R5
110: Counter
111: Input / Output
サンプルプログラム
code:1_Save_Load
const add 0
const add_ri 64
const add_ii 192
const sub 1
const jeq 32
const jeq_ii 224
const jlt 34
const jlte 35
const sw 16
const lw 8
const r0 0
const r1 1
const r2 2
const r3 3
const r4 4
const r5 5
const counter 6
const input 7
const output 7
expect 1 0
add_ii
0
0
r1
expect 2 10
add_ii
10
0
r2
sw
r1
r2
0
expect 3 10
lw
r1
0
r3
expect 1 1
add_ri
r1
1
r1
expect 2 20
add_ri
r2
10
r2
sw
r1
r2
0
expect 3 20
lw
r1
0
r3
code:foo
const add 0
const add_ri 64
const add_ii 192
const sub 1
const jeq 32
const jeq_ii 224
const jlt 34
const jlte 35
const sw 16
const lw 8
const r0 0
const r1 1
const r2 2
const r3 3
const r4 4
const r5 5
const counter 6
const input 7
const output 7
add_ri
input
0
r1
add_ri
input
0
r2
label loop
jlt
r1
r2
break
sub
r1
r2
r1
add_ri
r3
1
r3
jeq
r0
r0
loop
label break
# out quotient
add
r3
r0
output
# out remainder
add
r1
r0
output