some of it
This commit is contained in:
95
A5/encoding.txt
Normal file
95
A5/encoding.txt
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
x86prime instructions and encoding
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
Encoding: Assembler Operation
|
||||||
|
|
||||||
|
00000000 00000000 stop stop the machine
|
||||||
|
00000001 0000ssss ret s return from function call
|
||||||
|
0001aaaa ddddssss op s,d reg/reg arithmetic (see below)
|
||||||
|
00100001 ddddssss movq s,d reg->reg copy
|
||||||
|
00110001 ddddssss movq (s),d load (memory -> reg copy)
|
||||||
|
00111001 ddddssss movq d,(s) store (reg -> memory copy)
|
||||||
|
-
|
||||||
|
0100cccc ddddssss pp...32...pp cb<c> s,d,p compare and continue at p if... (see below)
|
||||||
|
01001110 dddd0000 pp...32...pp call p,d function call
|
||||||
|
01001111 00000000 pp...32...pp jmp p continue at p
|
||||||
|
0101aaaa dddd0000 ii...32...ii op $i,d constant/reg arithmethic(see below)
|
||||||
|
01100100 dddd0000 ii...32...ii movq $i,d constant -> register
|
||||||
|
01110101 ddddssss ii...32...ii movq i(s),d load (memory -> reg copy)
|
||||||
|
01111101 ddddssss ii...32...ii movq d,i(s) store (reg -> memory copy)
|
||||||
|
-
|
||||||
|
10000001 ddddssss leaq (s),d s -> d
|
||||||
|
10010010 dddd0000 zzzzvvvv leaq (,z,v),d z*v -> d
|
||||||
|
10010011 ddddssss zzzzvvvv leaq (s,z,v),d s+z*v -> d
|
||||||
|
10100100 dddd0000 ii...32...ii leaq i,d i -> d
|
||||||
|
10100101 ddddssss ii...32...ii leaq i(s),d i+s -> d
|
||||||
|
10110110 dddd0000 zzzzvvvv ii...32...ii leaq i(,z,v),d i+z*v -> d
|
||||||
|
10110111 ddddssss zzzzvvvv ii...32...ii leaq i(s,z,v),d i+s+z*v -> d
|
||||||
|
-
|
||||||
|
1111cccc dddd0000 ii...32...ii pp...32...pp cb<c> $i,d,p compare and continue at p if... (see below)
|
||||||
|
|
||||||
|
Note: first 4 bits are called the "major opcode", next 4 bits are called the "minor opcode".
|
||||||
|
|
||||||
|
Explanations:
|
||||||
|
|
||||||
|
aaaa indicates the kind of arithmetic operation. All operate on full 64 bits:
|
||||||
|
|
||||||
|
0000 add addition
|
||||||
|
0001 sub subtraction
|
||||||
|
0010 and bitwise and
|
||||||
|
0011 or bitwise or
|
||||||
|
0100 xor bitwise xor
|
||||||
|
0101 mul unsigned multiplication
|
||||||
|
0110 sar shift arithmetic right (preserve topmost bit)
|
||||||
|
0111 sal shift arithmetic left (zero into lsb, do not preserve topmost bit)
|
||||||
|
1000 shr shift (logical) right (zero into topmost bit)
|
||||||
|
1001 imul signed multiplication
|
||||||
|
|
||||||
|
d,s and z are registers:
|
||||||
|
|
||||||
|
0000 %rax 1000 %r8
|
||||||
|
0001 %rbx 1001 %r9
|
||||||
|
0010 %rcx 1010 %r10
|
||||||
|
0011 %rdx 1011 %r11
|
||||||
|
0100 %rbp 1100 %r12
|
||||||
|
0101 %rsi 1101 %r13
|
||||||
|
0110 %rdi 1110 %r14
|
||||||
|
0111 %rsp 1111 %r15
|
||||||
|
|
||||||
|
v is a scale factor encoded into the field vvvv in the form of a shift amount as follows:
|
||||||
|
|
||||||
|
vvvv v
|
||||||
|
0000 1
|
||||||
|
0001 2
|
||||||
|
0010 4
|
||||||
|
0011 8
|
||||||
|
|
||||||
|
ii...32...ii is a 32 bit signed immediate
|
||||||
|
pp...32...pp is a 32 bit target address
|
||||||
|
|
||||||
|
<c> is a condition mnemonic used in compare-and-branch. The compare-and-branch
|
||||||
|
instruction cb<c> is not part of the original x86 instruction set, but the
|
||||||
|
conditions in x86prime carry the same meaning as for x86.
|
||||||
|
|
||||||
|
Example: cble %rdi,%rbp,target = if %rdi <= %rbp (signed) then jump to target
|
||||||
|
|
||||||
|
Encoding Semantic
|
||||||
|
0000 e Equal
|
||||||
|
0001 ne Not equal
|
||||||
|
0010 <reserved>
|
||||||
|
0011 <reserved>
|
||||||
|
0100 l less (signed)
|
||||||
|
0101 le less or equal (signed)
|
||||||
|
0110 g greater (signed)
|
||||||
|
0111 ge greater or equal (signed)
|
||||||
|
1000 a above (unsigned)
|
||||||
|
1001 ae above or equal (unsigned)
|
||||||
|
1010 b below (unsigned)
|
||||||
|
1011 be below or equal (unsigned)
|
||||||
|
11xx <reserved>
|
||||||
|
|
||||||
|
Note that signed and unsigned comparisons are different.
|
||||||
|
|
||||||
|
call places the return address in a register instead of pushing it onto the stack.
|
||||||
|
ret returns to the address in a register instead of popping it from the stack.
|
||||||
|
returning to address 0 or to a negative address (bit 64 set) stops the machine.
|
34
A5/main.c
34
A5/main.c
@ -105,6 +105,7 @@ int main(int argc, char* argv[]) {
|
|||||||
val reg_s = pick_bits(0, 4, inst_bytes[1]);
|
val reg_s = pick_bits(0, 4, inst_bytes[1]);
|
||||||
val reg_z = pick_bits(4, 4, inst_bytes[2]);
|
val reg_z = pick_bits(4, 4, inst_bytes[2]);
|
||||||
val shamt = pick_bits(0, 4, inst_bytes[2]);
|
val shamt = pick_bits(0, 4, inst_bytes[2]);
|
||||||
|
val target = pick_bits(0, 8, inst_bytes[2]);
|
||||||
|
|
||||||
// decode instruction type from major operation code
|
// decode instruction type from major operation code
|
||||||
bool is_return_or_stop = is(RETURN_STOP, major_op);
|
bool is_return_or_stop = is(RETURN_STOP, major_op);
|
||||||
@ -122,9 +123,24 @@ int main(int argc, char* argv[]) {
|
|||||||
bool is_imm_cbranch = is(IMM_CBRANCH, major_op);
|
bool is_imm_cbranch = is(IMM_CBRANCH, major_op);
|
||||||
|
|
||||||
// Right now, we can only execute instructions with a size of 2.
|
// Right now, we can only execute instructions with a size of 2.
|
||||||
// TODO 2021:
|
|
||||||
// from info above determine the instruction size
|
// from info above determine the instruction size
|
||||||
val ins_size = from_int(2);
|
bool size_is_2 = (is_return_or_stop || is_reg_arithmetic || is_reg_movq || is_reg_movq_mem || is_leaq2);
|
||||||
|
val size_2 = use_if(size_is_2, from_int(2));
|
||||||
|
bool size_is_3 = (is_leaq3);
|
||||||
|
val size_3 = use_if(size_is_3, from_int(3));
|
||||||
|
bool size_is_6 = (is_cflow || is_imm_arithmetic || is_imm_movq || is_imm_movq_mem || is_leaq6);
|
||||||
|
val size_6 = use_if(size_is_6, from_int(6));
|
||||||
|
bool size_is_7 = (is_leaq7);
|
||||||
|
val size_7 = use_if(size_is_7, from_int(7));
|
||||||
|
bool size_is_10 = (is_imm_cbranch);
|
||||||
|
val size_10 = use_if(size_is_10, from_int(10));
|
||||||
|
|
||||||
|
val add_1 = add(size_2, size_3);
|
||||||
|
val add_2 = add(add_1, size_6);
|
||||||
|
val add_3 = add(add_2, size_7);
|
||||||
|
val add_4 = add(add_3, size_10);
|
||||||
|
|
||||||
|
val ins_size = add_4;
|
||||||
|
|
||||||
// broad categorization of the instruction
|
// broad categorization of the instruction
|
||||||
bool is_leaq = is_leaq2 || is_leaq3 || is_leaq6 || is_leaq7;
|
bool is_leaq = is_leaq2 || is_leaq3 || is_leaq6 || is_leaq7;
|
||||||
@ -139,9 +155,9 @@ int main(int argc, char* argv[]) {
|
|||||||
bool imm_p_pos6 = is_imm_cbranch; /* all other at position 2 */
|
bool imm_p_pos6 = is_imm_cbranch; /* all other at position 2 */
|
||||||
|
|
||||||
// unimplemented control signals:
|
// unimplemented control signals:
|
||||||
bool is_load = false; // TODO 2021: Detect when we're executing a load
|
bool is_load = (is_mem_access && !pick_one(3,minor_op));
|
||||||
bool is_store = false; // TODO 2021: Detect when we're executing a store
|
bool is_store = (is_mem_access && pick_one(3,minor_op));
|
||||||
bool is_conditional = false; // TODO 2021: Detect if we are executing a conditional flow change
|
bool is_conditional = (is_cflow || is_imm_cbranch) && !(is(0xE, minor_op) || is(0xF, minor_op));
|
||||||
|
|
||||||
// TODO 2021: Add additional control signals you may need below....
|
// TODO 2021: Add additional control signals you may need below....
|
||||||
|
|
||||||
@ -214,8 +230,11 @@ int main(int argc, char* argv[]) {
|
|||||||
val pc_incremented = add(pc, ins_size);
|
val pc_incremented = add(pc, ins_size);
|
||||||
|
|
||||||
// determine the next position of the program counter
|
// determine the next position of the program counter
|
||||||
// TODO 2021: Add any additional sources for the next PC (for call, ret, jmp and conditional branch)
|
bool is_jump = is_cflow && (is(0xF,minor_op) || (is_conditional && !reduce_or(compute_result)));
|
||||||
val pc_next = pc_incremented;
|
val pc_next_if_not_control = use_if(!is_jump, pc_incremented);
|
||||||
|
val pc_next_if_jump = use_if(is_jump, target);
|
||||||
|
val pc_next_if_return = use_if(is_return, reg_out_b);
|
||||||
|
val pc_next = add(add(pc_next_if_not_control, pc_next_if_jump), pc_next_if_return);
|
||||||
|
|
||||||
/*** MEMORY ***/
|
/*** MEMORY ***/
|
||||||
// read from memory if needed
|
// read from memory if needed
|
||||||
@ -232,6 +251,7 @@ int main(int argc, char* argv[]) {
|
|||||||
reg_write(regs, reg_d, datapath_result, reg_wr_enable);
|
reg_write(regs, reg_d, datapath_result, reg_wr_enable);
|
||||||
|
|
||||||
// write to memory if needed
|
// write to memory if needed
|
||||||
|
printf("%i\n",is_store);
|
||||||
memory_write(mem, agen_result, reg_out_a, is_store);
|
memory_write(mem, agen_result, reg_out_a, is_store);
|
||||||
|
|
||||||
// update program counter
|
// update program counter
|
||||||
|
17
A5/test_runs/test1.hex
Normal file
17
A5/test_runs/test1.hex
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
00000000 : # test:
|
||||||
|
00000000 : A45030000000 # leaq data, %rsi
|
||||||
|
00000006 : 640000000000 # movq $0, %rax
|
||||||
|
0000000c : 644000000000 # movq $0, %rbp
|
||||||
|
00000012 : 93B503 # leaq (%rsi, %rax, 8), %r11
|
||||||
|
00000015 : 313B # movq (%r11), %rdx
|
||||||
|
00000017 : 500001000000 # addq $1, %rax
|
||||||
|
0000001d : 1043 # addq %rdx, %rbp
|
||||||
|
0000001f : 93B503 # leaq (%rsi, %rax, 8), %r11
|
||||||
|
00000022 : 313B # movq (%r11), %rdx
|
||||||
|
00000024 : 500001000000 # addq $1, %rax
|
||||||
|
0000002a : 1043 # addq %rdx, %rbp
|
||||||
|
0000002c : 0000 # stop
|
||||||
|
00000030 : # .align 8
|
||||||
|
00000030 : # data:
|
||||||
|
00000030 : 2a00000000000000 # .quad 42
|
||||||
|
00000038 : 1500000000000000 # .quad 21
|
25
A5/test_runs/test1.out
Normal file
25
A5/test_runs/test1.out
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
1 0
|
||||||
|
0
|
||||||
|
2 6
|
||||||
|
0
|
||||||
|
3 c
|
||||||
|
0
|
||||||
|
4 12
|
||||||
|
0
|
||||||
|
5 15
|
||||||
|
0
|
||||||
|
6 17
|
||||||
|
0
|
||||||
|
7 1d
|
||||||
|
0
|
||||||
|
8 1f
|
||||||
|
0
|
||||||
|
9 22
|
||||||
|
0
|
||||||
|
10 24
|
||||||
|
0
|
||||||
|
11 2a
|
||||||
|
0
|
||||||
|
12 2c
|
||||||
|
0
|
||||||
|
Done
|
2
A5/test_runs/test1.sym
Normal file
2
A5/test_runs/test1.sym
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
data : 00000030
|
||||||
|
test : 00000000
|
24
A5/test_runs/test1.trc
Normal file
24
A5/test_runs/test1.trc
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
P 0 0
|
||||||
|
R 5 30
|
||||||
|
P 0 6
|
||||||
|
R 0 0
|
||||||
|
P 0 c
|
||||||
|
R 4 0
|
||||||
|
P 0 12
|
||||||
|
R b 30
|
||||||
|
P 0 15
|
||||||
|
R 3 2a
|
||||||
|
P 0 17
|
||||||
|
R 0 1
|
||||||
|
P 0 1d
|
||||||
|
R 4 2a
|
||||||
|
P 0 1f
|
||||||
|
R b 38
|
||||||
|
P 0 22
|
||||||
|
R 3 15
|
||||||
|
P 0 24
|
||||||
|
R 0 2
|
||||||
|
P 0 2a
|
||||||
|
R 4 3f
|
||||||
|
P 0 2c
|
||||||
|
P 0 2e
|
22
A5/test_runs/test2.hex
Normal file
22
A5/test_runs/test2.hex
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
00000000 : # test:
|
||||||
|
00000000 : 517008000000 # subq $8, %rsp
|
||||||
|
00000006 : 39B7 # movq %r11, (%rsp)
|
||||||
|
00000008 : 938623 # leaq (%rdi, %rcx, 8), %r8
|
||||||
|
0000000b : 4F0025000000 # jmp .L6
|
||||||
|
00000011 : # .L7:
|
||||||
|
00000011 : 3906 # movq %rax, (%rdi)
|
||||||
|
00000013 : # .L8:
|
||||||
|
00000013 : 506008000000 # addq $8, %rdi
|
||||||
|
00000019 : 505008000000 # addq $8, %rsi
|
||||||
|
0000001f : 503008000000 # addq $8, %rdx
|
||||||
|
00000025 : # .L6:
|
||||||
|
00000025 : 4B683d000000 # cbbe %r8, %rdi, .L10
|
||||||
|
0000002b : 3125 # movq (%rsi), %rcx
|
||||||
|
0000002d : 3103 # movq (%rdx), %rax
|
||||||
|
0000002f : 472011000000 # cbge %rax, %rcx, .L7
|
||||||
|
00000035 : 3926 # movq %rcx, (%rdi)
|
||||||
|
00000037 : 4F0013000000 # jmp .L8
|
||||||
|
0000003d : # .L10:
|
||||||
|
0000003d : 31B7 # movq (%rsp), %r11
|
||||||
|
0000003f : 507008000000 # addq $8, %rsp
|
||||||
|
00000045 : 010B # ret %r11
|
18
A5/test_runs/test2.out
Normal file
18
A5/test_runs/test2.out
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
1 0
|
||||||
|
0
|
||||||
|
2 6
|
||||||
|
1
|
||||||
|
3 8
|
||||||
|
0
|
||||||
|
4 b
|
||||||
|
0
|
||||||
|
5 25
|
||||||
|
0
|
||||||
|
6 3d
|
||||||
|
0
|
||||||
|
7 3f
|
||||||
|
0
|
||||||
|
8 45
|
||||||
|
0
|
||||||
|
-- value mismatch, access 'P' 0
|
||||||
|
-- with value 47, but tracefile expected 0
|
5
A5/test_runs/test2.sym
Normal file
5
A5/test_runs/test2.sym
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
.L10 : 0000003d
|
||||||
|
.L6 : 00000025
|
||||||
|
.L8 : 00000013
|
||||||
|
.L7 : 00000011
|
||||||
|
test : 00000000
|
14
A5/test_runs/test2.trc
Normal file
14
A5/test_runs/test2.trc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
P 0 0
|
||||||
|
R 7 fffffffffffffff8
|
||||||
|
P 0 6
|
||||||
|
M fffffffffffffff8 0
|
||||||
|
P 0 8
|
||||||
|
R 8 0
|
||||||
|
P 0 b
|
||||||
|
P 0 25
|
||||||
|
P 0 3d
|
||||||
|
R b 0
|
||||||
|
P 0 3f
|
||||||
|
R 7 0
|
||||||
|
P 0 45
|
||||||
|
P 0 0
|
18
A5/tests/test1.prime
Normal file
18
A5/tests/test1.prime
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
test:
|
||||||
|
leaq data,%rsi
|
||||||
|
movq $0,%rax
|
||||||
|
movq $0,%rbp
|
||||||
|
leaq (%rsi, %rax, 8),%r11
|
||||||
|
movq (%r11),%rdx
|
||||||
|
addq $1,%rax
|
||||||
|
addq %rdx,%rbp
|
||||||
|
leaq (%rsi, %rax, 8), %r11
|
||||||
|
movq (%r11), %rdx
|
||||||
|
addq $1, %rax
|
||||||
|
addq %rdx,%rbp
|
||||||
|
stop
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
data:
|
||||||
|
.quad 42
|
||||||
|
.quad 21
|
22
A5/tests/test2.prime
Normal file
22
A5/tests/test2.prime
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
test:
|
||||||
|
subq $8, %rsp
|
||||||
|
movq %r11, (%rsp)
|
||||||
|
leaq (%rdi, %rcx, 8), %r8
|
||||||
|
jmp .L6
|
||||||
|
.L7:
|
||||||
|
movq %rax, (%rdi)
|
||||||
|
.L8:
|
||||||
|
addq $8, %rdi
|
||||||
|
addq $8, %rsi
|
||||||
|
addq $8, %rdx
|
||||||
|
.L6:
|
||||||
|
cbbe %r8, %rdi, .L10
|
||||||
|
movq (%rsi), %rcx
|
||||||
|
movq (%rdx), %rax
|
||||||
|
cbge %rax, %rcx, .L7
|
||||||
|
movq %rcx, (%rdi)
|
||||||
|
jmp .L8
|
||||||
|
.L10:
|
||||||
|
movq (%rsp), %r11
|
||||||
|
addq $8, %rsp
|
||||||
|
ret %r11
|
Reference in New Issue
Block a user