Last active
March 31, 2020 06:58
-
-
Save dannas/dc147b230a9ee8af8b9a969ef21e85c7 to your computer and use it in GitHub Desktop.
Program for experimenting with C code generation of x86-64 mov instructions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdint.h> | |
| // Program for experimenting with C code generation of x86-64 mov instructions. | |
| // https://godbolt.org/z/7UPcax | |
| // | |
| // The x86-64 has grown from the original x86 16-bit arch. A word in Intel terminology is still 16-bits (2 bytes). | |
| // A list of instruction size suffixes | |
| // b Byte | |
| // w Word | |
| // l Double-Word | |
| // q Quad-Word | |
| // | |
| // The original x86 arch had eight registers (ax, bx, cx, dx, di, si, sp, bp). They are named on this form. | |
| // al Byte | |
| // ax Word | |
| // eax Double-Word | |
| // rax Quad-Word | |
| // | |
| // The x86-64 arch added eight registers r8-r15 | |
| // r8b Byte | |
| // r8w Word | |
| // r8d Double-Word | |
| // r8 Quad-Word | |
| // | |
| // There are three categories of mov instructions. (X is size of src, Y is size of dest) | |
| // movX src, dest ; dest = src | |
| // movzXY src,dest ; dest = ZeroExtend(src). | |
| // movsXY src,dest ; dest = SignExtend(src). | |
| // | |
| // The operands of a mov, movz, movs instruction can be any of these pairs (more than these exists). | |
| // reg-reg | |
| // reg-mem | |
| // mem-reg | |
| // imm-reg | |
| // imm-mem | |
| // | |
| // Some quirks: | |
| // * movb and movw moves a reg to the lower part of the dest, but leaves the upper bits untouched. | |
| // But movl zeroes out the upper bits. Due to this, no movzlq instruction exists - movl is unsed instead. | |
| // * movq imm, reg only moves 4 bytes and sign extends the upper 4 bytes. For moving an 8 imm, movabsq is | |
| // needed. | |
| // Aliases for increased readability | |
| typedef uint8_t u8; | |
| typedef uint16_t u16; | |
| typedef uint32_t u32; | |
| typedef uint64_t u64; | |
| typedef int8_t i8; | |
| typedef int16_t i16; | |
| typedef int32_t i32; | |
| typedef int64_t i64; | |
| // Generates a reg-reg mov instruction. | |
| #define RR(Src, Dest) Dest reg_ ## Src ## _to_ ## Dest(Src val) { return val;} | |
| // Generates a imm-reg mov instruction. | |
| #define IR(Src, Dest) Dest imm_ ## Src ## _to_ ## Dest(void) { return (Src)0x1122334455667788L; } | |
| // Generates a mem-reg, then reg-mem instruction pair. | |
| #define MM(Src, Dest) void mem_ ## Src ## _to_ ## Dest(Dest *dst, Src *src) {*dst = (Dest)*src; } | |
| // Widening unsigned reg-reg conversions | |
| RR(u8, u16) | |
| RR(u8, u32) | |
| RR(u8, u64) | |
| RR(u16, u32) | |
| RR(u16, u64) | |
| RR(u32, u64) | |
| // Wideninig signed reg-reg conversions | |
| RR(i8, i16) | |
| RR(i8, i32) | |
| RR(i8, i64) | |
| RR(i16, i32) | |
| RR(i16, i64) | |
| RR(i32, i64) | |
| // Unsigned imm-reg conversions | |
| IR(u8, u8) | |
| IR(u8, u16) | |
| IR(u8, u32) | |
| IR(u8, u64) | |
| IR(u16, u16) | |
| IR(u16, u32) | |
| IR(u16, u64) | |
| IR(u32, u32) | |
| IR(u32, u64) | |
| IR(u64, u64) | |
| // Signed imm-reg conversions | |
| IR(i8, i8) | |
| IR(i8, i16) | |
| IR(i8, i32) | |
| IR(i8, i64) | |
| IR(i16, i16) | |
| IR(i16, i32) | |
| IR(i16, i64) | |
| IR(i32, i32) | |
| IR(i32, i64) | |
| IR(i64, i64) | |
| // Widenining unsigned mem-mem conversions | |
| MM(u8, u16) | |
| MM(u8, u32) | |
| MM(u8, u64) | |
| MM(u16, u32) | |
| MM(u16, u64) | |
| MM(u32, u64) | |
| // Widenining unsigned-signed mem-mem conversions | |
| MM(u8, i16) | |
| MM(u8, i32) | |
| MM(u8, i64) | |
| MM(u16, i32) | |
| MM(u16, i64) | |
| MM(u32, i64) | |
| // Widenining signed mem-mem conversions | |
| MM(i8, i16) | |
| MM(i8, i32) | |
| MM(i8, i64) | |
| MM(i16, i32) | |
| MM(i16, i64) | |
| MM(i32, i64) | |
| // Widenining signed-unsigned mem-mem conversions | |
| MM(i8, u16) | |
| MM(i8, u32) | |
| MM(i8, u64) | |
| MM(i16, u32) | |
| MM(i16, u64) | |
| MM(i32, u64) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment