1 /**
2 * Assembly CTFE Helpers for 64-bit x86
3 * 
4 * Copyright:
5 * (C) 1999-2008 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.utils.asm_x86_64.asm_x86_64;
12 import std.conv : to;
13 pure:
14 // todo : LDC / GDC asm
15 
16 /*
17 * General/Global Macros
18 */
19 
20 enum START_ASM = "asm pure nothrow {";
21 enum END_ASM = "}";
22 enum ALIGN = "align 16";
23 
24 /*
25 * Conditional Jumps
26 */
27 string JUMP_IF_ZERO(string REG, string LABEL)() {
28     return "cmp " ~ REG ~ ", " ~ IMM(0) ~ ";
29             jz " ~ LABEL ~ ";\n";
30 }
31 
32 string JUMP_IF_LT(string REG, int NUM, string LABEL) {
33     return "cmp " ~ IMM(NUM) ~ ", " ~ REG ~ ";
34             jl " ~ LABEL ~ ";\n";
35 }
36 
37 /*
38 * Register Names
39 */
40 enum R0 = "RAX";
41 enum R1 = "RBX";
42 enum R2 = "RCX";
43 enum R2_32 = "ECX";
44 enum R3 = "RDX";
45 enum R3_32 = "EDX";
46 enum R4 = "RSP";
47 enum R5 = "RBP";
48 enum R6 = "RSI";
49 enum R6_32 = "ESI";
50 enum R7 = "RDI";
51 enum R8 = "R8";
52 enum R9 = "R9";
53 enum R9_32 = "R9D";
54 enum R10 = "R10";
55 enum R11 = "R11";
56 enum R12 = "R12";
57 enum R13 = "R13";
58 enum R14 = "R14";
59 enum R15 = "R15";
60 enum R16 = "R16";
61 
62 enum ARG_1 = R7;
63 enum ARG_2 = R6;
64 enum ARG_2_32 = R6_32;
65 enum ARG_3 = R3;
66 enum ARG_3_32 = R3_32;
67 enum ARG_4 = R2;
68 enum ARG_4_32 = R2_32;
69 enum ARG_5 = R8;
70 enum ARG_6 = R9;
71 enum ARG_6_32 = R9_32;
72 
73 enum TEMP_1 = R10;
74 enum TEMP_2 = R11;
75 enum TEMP_3 = ARG_6;
76 enum TEMP_4 = ARG_5;
77 enum TEMP_5 = ARG_4;
78 enum TEMP_5_32 = ARG_4_32;
79 enum TEMP_6 = ARG_3;
80 enum TEMP_7 = ARG_2;
81 enum TEMP_8 = ARG_1;
82 enum TEMP_9 = R0;
83 
84 /*
85 * Memory Access Operations
86 */
87 string ARRAY4(string REG, int NUM) { return "[" ~ REG ~ " + " ~ (4*NUM).to!string ~ "]"; }
88 string ARRAY8(string REG, int NUM) { return "[" ~ REG ~ " + " ~ (8*NUM).to!string ~ "]"; }
89 string ASSIGN(string TO, string FROM) { return "mov " ~ TO ~ ", " ~ FROM ~ ";\n"; }
90 
91 
92 /*
93 * ALU Operations
94 */
95 string IMM(int VAL) { return VAL.to!string; }
96 
97 string ADD(string TO, string FROM) { return "add " ~ TO ~ ", " ~ FROM ~ ";\n"; }
98 string ADD_IMM(string TO, int NUM) { return ADD(TO, IMM(NUM)); }
99 string ADD_LAST_CARRY(string REG) { return "adc " ~ REG ~ ", " ~ IMM(0) ~ ";\n"; }
100 string ADD_W_CARRY(string TO1, string TO2, string FROM) { return "add " ~ TO1 ~ ", " ~ FROM ~ ";\nadc " ~ TO2 ~ ", " ~ IMM(0) ~ ";\n"; }
101 string SUB_IMM(string TO, int NUM) { return "sub " ~ TO ~ ", " ~ IMM(NUM) ~ ";\n"; }
102 string MUL(string REG) { return "mul " ~ REG ~ ";\n"; }
103 
104 string XOR(string TO, string FROM) { return "xor " ~ TO ~ ", " ~ FROM ~ ";\n"; }
105 string AND(string TO, string FROM) { return "and " ~ TO ~ ", " ~ FROM ~ ";\n"; }
106 string OR(string TO, string FROM) { return "or " ~ TO ~ ", " ~ FROM ~ ";\n"; }
107 string NOT(string REG) { return "not " ~ REG ~ ";\n"; }
108 string ZEROIZE(string REG) { return XOR(REG, REG); }
109 
110 
111 string ROTL_IMM(string REG, int NUM) { return "rol " ~ REG ~ ", " ~ IMM(NUM) ~ ";\n"; }
112 string ROTR_IMM(string REG, int NUM) { return "ror " ~ REG ~ ", " ~ IMM(NUM) ~ ";\n"; }
113 string ADD3_IMM(string TO, string FROM, int NUM) { return "lea " ~ TO ~ ", [" ~ TO ~ " + " ~ NUM.to!string ~ " + " ~ FROM ~ "];\n"; }