Skip to content

Commit da8d5be

Browse files
committed
add MOV implementation
1 parent 0777da2 commit da8d5be

File tree

2 files changed

+166
-18
lines changed

2 files changed

+166
-18
lines changed

asm_during_compiling/include/Opcode.h

+143-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
#ifndef OPCODE_H
22
#define OPCODE_H
33

4-
// ADD_LIKE r8 , imm8 -- op1 /0 ib
5-
// ADD_LIKE r16, imm8 -- op2 /0 ib
6-
// ADD_LIKE r32, imm8 -- op2 /0 ib
7-
// ADD_LIKE r64, imm8 -- REX.W + op2 /0 ib
8-
// ADD_LIKE r16, imm16 -- op3 /0 iw
9-
// ADD_LIKE r32, imm32 -- op3 /0 id
10-
// ADD_LIKE r64, imm32 -- REX.W + op3 /0 id
4+
// ADD_LIKE r8 , imm8 -- op1 /digit ib
5+
// ADD_LIKE r16, imm8 -- op2 /digit ib
6+
// ADD_LIKE r32, imm8 -- op2 /digit ib
7+
// ADD_LIKE r64, imm8 -- REX.W + op2 /digit ib
8+
// ADD_LIKE r16, imm16 -- op3 /digit iw
9+
// ADD_LIKE r32, imm32 -- op3 /digit id
10+
// ADD_LIKE r64, imm32 -- REX.W + op3 /digit id
1111
template <uint8_t digit, uint8_t op_1, uint8_t op_2, uint8_t op_3,
1212
size_t s, size_t i,
1313
size_t imms, typename Immediate_type<imms>::type x, bool is_var>
@@ -35,13 +35,13 @@ constexpr auto ADD_LIKE (Register<s, i> reg, Immediate<imms, x, is_var> imm)
3535
}
3636
}
3737

38-
// ADD_LIKE m8, imm8 -- op1 /0 ib
39-
// ADD_LIKE m16, imm8 -- op2 /0 ib
40-
// ADD_LIKE m32, imm8 -- op2 /0 ib
41-
// ADD_LIKE m64, imm8 -- REX.W + op2 /0 ib
42-
// ADD_LIKE m16, imm16 -- op3 /0 iw
43-
// ADD_LIKE m32, imm32 -- op3 /0 id
44-
// ADD_LIKE m64, imm32 -- REX.W + op3 /0 id
38+
// ADD_LIKE m8, imm8 -- op1 /digit ib
39+
// ADD_LIKE m16, imm8 -- op2 /digit ib
40+
// ADD_LIKE m32, imm8 -- op2 /digit ib
41+
// ADD_LIKE m64, imm8 -- REX.W + op2 /digit ib
42+
// ADD_LIKE m16, imm16 -- op3 /digit iw
43+
// ADD_LIKE m32, imm32 -- op3 /digit id
44+
// ADD_LIKE m64, imm32 -- REX.W + op3 /digit id
4545
template <uint8_t digit, uint8_t op_1, uint8_t op_2, uint8_t op_3,
4646
size_t s, typename r1, typename r2, typename scale, typename disp,
4747
size_t imms, typename Immediate_type<imms>::type x, bool is_var>
@@ -69,6 +69,31 @@ constexpr auto ADD_LIKE (Memory<s, r1, r2, scale, disp> mem, Immediate<imms, x,
6969
}
7070
}
7171

72+
// ADD_LIKE m8, imm8 -- op1 /digit ib
73+
// ADD_LIKE m16, imm16 -- op2 /digit iw
74+
// ADD_LIKE m32, imm32 -- op2 /digit id
75+
// ADD_LIKE m64, imm64 -- REX.W + op2 /digit id
76+
template <uint8_t digit, uint8_t op_1, uint8_t op_2,
77+
size_t s, typename r1, typename r2, typename scale, typename disp,
78+
size_t imms, typename Immediate_type<imms>::type x, bool is_var>
79+
constexpr auto ADD_LIKE_SAME_SIZE (Memory<s, r1, r2, scale, disp> mem, Immediate<imms, x, is_var> imm)
80+
{
81+
if constexpr (is_m8(mem) && is_imm8(imm))
82+
{
83+
return rex<0, 0>(mem) + opcode<op_1>() + modrm<digit>(mem) + to_bytes(imm);
84+
}
85+
else if constexpr ((is_m16(mem) && is_imm16(imm)) ||
86+
(is_m32(mem) && is_imm32(imm)) ||
87+
(is_m64(mem) && is_imm32(imm)))
88+
{
89+
return rex<is_m64(mem)?1:0, 0>(mem) + opcode<op_2>() + modrm<digit>(mem) + to_bytes(imm);
90+
}
91+
else
92+
{
93+
94+
}
95+
}
96+
7297
// ADD_LIKE r8, r8 -- op1 /r
7398
// ADD_LIKE r16, r16 -- op2 /r
7499
// ADD_LIKE r32, r32 -- op2 /r
@@ -410,6 +435,110 @@ constexpr auto INC (Memory<memsize, r1, r2, scale, disp> mem)
410435
}
411436
}
412437

438+
439+
// JE rel8
440+
// JE rel32
441+
//template <size_t s, typename Immediate_type<imms>::type x, bool is_var>
442+
//constexpr auto JE (Immediate<s, x, is_var> imm)
443+
//{
444+
// if constexpr (is_imm8(imm))
445+
// {
446+
// return opcode<'\x74'>() + to_bytes(imm);
447+
// }
448+
// else if constexpr (is_imm32(imm))
449+
// {
450+
// return opcode<'\x0f'>() + opcode<'\x84'>() + to_bytes(imm);
451+
// }
452+
// else
453+
// {
454+
//
455+
// }
456+
//}
457+
458+
// JNE rel8
459+
// JNE rel32
460+
//template <size_t s, typename Immediate_type<imms>::type x, bool is_var>
461+
//constexpr auto JNE (Immediate<s, x, is_var> imm)
462+
//{
463+
// if constexpr (is_imm8(imm))
464+
// {
465+
// return opcode<'\x75'>() + to_bytes(imm);
466+
// }
467+
// else if constexpr (is_imm32(imm))
468+
// {
469+
// return opcode<'\x0f'>() + opcode<'\x85'>() + to_bytes(imm);
470+
// }
471+
// else
472+
// {
473+
//
474+
// }
475+
//}
476+
477+
// MOV r8, imm8 -- c6 /0 ib
478+
// MOV r16, imm16 -- c7 /0 iw
479+
// MOV r32, imm32 -- c7 /0 id
480+
// MOV r64, imm64 -- REX.W + c7 /0 /id
481+
template <size_t s, size_t i,
482+
size_t imms, typename Immediate_type<imms>::type x, bool is_var>
483+
constexpr auto MOV (Register<s, i> reg, Immediate<imms, x, is_var> imm)
484+
{
485+
//return ADD_LIKE_SAME_SIZE<0, '\xc6', '\xc7'>(reg, imm);
486+
if constexpr (is_r8(reg) && is_imm8(imm))
487+
{
488+
return rex<0>(reg) + opcode<'\xb0' + reg.index % 8>() + to_bytes(imm);
489+
}
490+
else if constexpr ((is_r16(reg) && is_imm16(imm)) ||
491+
(is_r32(reg) && is_imm32(imm)) ||
492+
(is_r64(reg) && is_imm64(imm)))
493+
{
494+
return rex<is_r64(reg)?1:0>(reg) + opcode<'\xb8' + reg.index % 8>() + to_bytes(imm);
495+
}
496+
}
497+
498+
// MOV m8, imm8 -- c6 /0 ib
499+
// MOV m16, imm16 -- c7 /0 iw
500+
// MOV m32, imm32 -- c7 /0 id
501+
// MOV m64, imm32 -- REX.W + c7 /0 /id
502+
template <size_t s, typename r1, typename r2, typename scale, typename disp,
503+
size_t imms, typename Immediate_type<imms>::type x, bool is_var>
504+
constexpr auto MOV (Memory<s, r1, r2, scale, disp> mem, Immediate<imms, x, is_var> imm)
505+
{
506+
return ADD_LIKE_SAME_SIZE<0, '\xc6', '\xc7'>(mem, imm);
507+
}
508+
509+
// MOV r8, r8 -- 88 /r
510+
// MOV r16, r16 -- 89 /r
511+
// MOV r32, r32 -- 89 /r
512+
// MOV r64, r64 -- REX.W + 89 /r
513+
template <size_t s1, size_t i1, size_t s2, size_t i2>
514+
constexpr auto MOV (Register<s1, i1> reg1, Register<s2, i2> reg2)
515+
{
516+
return ADD_LIKE<'\x88', '\x89'>(reg1, reg2);
517+
}
518+
519+
// MOV m8, r8 -- 88 /r
520+
// MOV m16, r16 -- 89 /r
521+
// MOV m32, r32 -- 89 /r
522+
// MOV m64, r64 -- REX.W + 89 /r
523+
template <size_t memsize, typename r1, typename r2, typename scale, typename disp,
524+
size_t regsize, size_t i>
525+
constexpr auto MOV (Memory<memsize, r1, r2, scale, disp> mem, Register<regsize, i> reg)
526+
{
527+
return ADD_LIKE<'\x88', '\x89'>(mem, reg);
528+
}
529+
530+
// MOV r8, m8 -- 8a /r
531+
// MOV r16, m16 -- 8b /r
532+
// MOV r32, m32 -- 8b /r
533+
// MOV r64, m64 -- REX.W + 8b /r
534+
template <size_t regsize, size_t i,
535+
size_t memsize, typename r1, typename r2, typename scale, typename disp>
536+
constexpr auto MOV (Register<regsize, i> reg, Memory<memsize, r1, r2, scale, disp> mem)
537+
{
538+
return ADD_LIKE<'\x8a', '\x8b'>(reg, mem);
539+
}
540+
541+
413542
//! SYSCALL
414543
constexpr auto SYSCALL ()
415544
{

asm_during_compiling/test/OpcodeTest.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,32 @@ TEST_CASE("various opcodes", "[opcode]") {
9494
REQUIRE(INC(q_[rsp + rbp * 2_x + Imm8<0x7f>]) == BYTES(0x48, 0xff, 0x44, 0x6c, 0x7f));
9595
}
9696

97-
SECTION("JE") {
98-
}
99-
100-
SECTION("JNE") {
97+
SECTION("JE && JNE") {
98+
//JNE(Imm8<0x12>).print();
99+
//JNE(Imm8<-0x12>).print();
101100
}
102101

103102
SECTION("MOV") {
103+
MOV(bl, Imm8<0x12>) == BYTES(0xb3, 0x12);
104+
MOV(b_[rsp + rbp * 2_x + Imm8<0x7f>], Imm8<0x12>) == BYTES(0xc6, 0x44, 0x6c, 0x7f, 0x12);
105+
MOV(bx, Imm16<0x1234>) == BYTES(0x66, 0xbb, 0x34, 0x12);
106+
MOV(w_[rsp + rbp * 2_x + Imm8<0x7f>], Imm16<0x1234>) == BYTES(0x66, 0xc7, 0x44, 0x6c, 0x7f, 0x34, 0x12);
107+
MOV(ebx, Imm32<0x12345678>) == BYTES(0xbb, 0x78, 0x56, 0x34, 0x12);
108+
MOV(d_[rsp + rbp * 2_x + Imm8<0x7f>], Imm32<0x12345678>) == BYTES(0xc7, 0x44, 0x6c, 0x7f, 0x78, 0x56, 0x34, 0x12);
109+
MOV(rax, Imm64<0x1234567887654321>) == BYTES(0x48, 0xb8, 0x21, 0x43, 0x65, 0x87, 0x78, 0x56, 0x34, 0x12);
110+
MOV(q_[rsp + rbp * 2_x + Imm8<0x7f>], Imm32<0x12345678>) == BYTES(0x48, 0xc7, 0x44, 0x6c, 0x7f, 0x78, 0x56, 0x34, 0x12);
111+
MOV(bl, cl) == BYTES(0x88, 0xcb);
112+
MOV(b_[rsp + rbp * 2_x + Imm8<0x7f>], bl) == BYTES(0x88, 0x5c, 0x6c, 0x7f);
113+
MOV(bx, cx) == BYTES(0x66, 0x89, 0xcb);
114+
MOV(w_[rsp + rbp * 2_x + Imm8<0x7f>], bx) == BYTES(0x66, 0x89, 0x5c, 0x6c, 0x7f);
115+
MOV(ebx, ecx) == BYTES(0x89, 0xcb);
116+
MOV(d_[rsp + rbp * 2_x + Imm8<0x7f>], ebx) == BYTES(0x89, 0x5c, 0x6c, 0x7f );
117+
MOV(rbx, rcx) == BYTES(0x48, 0x89, 0xcb );
118+
MOV(q_[rsp + rbp * 2_x + Imm8<0x7f>], rbx) == BYTES(0x48, 0x89, 0x5c, 0x6c, 0x7f);
119+
MOV(bl, b_[rsp + rbp * 2_x + Imm8<0x7f>]) == BYTES(0x8a, 0x5c, 0x6c, 0x7f);
120+
MOV(bx, w_[rsp + rbp * 2_x + Imm8<0x7f>]) == BYTES(0x66, 0x8b, 0x5c, 0x6c, 0x7f);
121+
MOV(ebx, d_[rsp + rbp * 2_x + Imm8<0x7f>]) == BYTES(0x8b, 0x5c, 0x6c, 0x7f);
122+
MOV(rbx, q_[rsp + rbp * 2_x + Imm8<0x7f>]) == BYTES(0x48, 0x8b, 0x5c, 0x6c, 0x7f);
104123
}
105124

106125
SECTION("SUB") {

0 commit comments

Comments
 (0)