diff --git a/macros/smartalign.mac b/macros/smartalign.mac new file mode 100644 index 00000000..1a631edc --- /dev/null +++ b/macros/smartalign.mac @@ -0,0 +1,255 @@ +; +; Smart alignment macros +; +USE: smartalign + +%imacro alignmode 1-2.nolist + %ifnempty %2 + %xdefine __ALIGN_JMP_THRESHOLD__ %2 + %else + %define __ALIGN_JMP_THRESHOLD__ 17 + %endif + %ifidni %1,nop + %define __ALIGN_16BIT_1B__ 0x90 + %define __ALIGN_16BIT_2B__ 0x90,0x90 + %define __ALIGN_16BIT_3B__ 0x90,0x90,0x90 + %define __ALIGN_16BIT_4B__ 0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_5B__ 0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_6B__ 0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_7B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_8B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + %define __ALIGN_32BIT_1B__ 0x90 + %define __ALIGN_32BIT_2B__ 0x90,0x90 + %define __ALIGN_32BIT_3B__ 0x90,0x90,0x90 + %define __ALIGN_32BIT_4B__ 0x90,0x90,0x90,0x90 + %define __ALIGN_32BIT_5B__ 0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_32BIT_6B__ 0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_32BIT_7B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_32BIT_8B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + %define __ALIGN_64BIT_1B__ 0x90 + %define __ALIGN_64BIT_2B__ 0x90,0x90 + %define __ALIGN_64BIT_3B__ 0x90,0x90,0x90 + %define __ALIGN_64BIT_4B__ 0x90,0x90,0x90,0x90 + %define __ALIGN_64BIT_5B__ 0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_64BIT_6B__ 0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_64BIT_7B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_64BIT_8B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + %elifidni %1,generic + %define __ALIGN_16BIT_1B__ 0x90 + %define __ALIGN_16BIT_2B__ 0x90,0x90 + %define __ALIGN_16BIT_3B__ 0x90,0x90,0x90 + %define __ALIGN_16BIT_4B__ 0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_5B__ 0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_6B__ 0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_7B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90 + %define __ALIGN_16BIT_8B__ 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 + + %define __ALIGN_32BIT_1B__ 0x90 + %define __ALIGN_32BIT_2B__ 0x89,0xf6 + %define __ALIGN_32BIT_3B__ 0x8d,0x76,0x00 + %define __ALIGN_32BIT_4B__ 0x8d,0x74,0x26,0x00 + %define __ALIGN_32BIT_5B__ 0x90,0x8d,0x74,0x26,0x00 + %define __ALIGN_32BIT_6B__ 0x8d,0xb6,0x00,0x00,0x00,0x00 + %define __ALIGN_32BIT_7B__ 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00 + %undef __ALIGN_32BIT_8B__ + + %define __ALIGN_64BIT_1B__ 0x90 + %define __ALIGN_64BIT_2B__ 0x66,0x90 + %define __ALIGN_64BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_64BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_64BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_64BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + %elifidni %1,k8 + %define __ALIGN_16BIT_1B__ 0x90 + %define __ALIGN_16BIT_2B__ 0x66,0x90 + %define __ALIGN_16BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_16BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_16BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_16BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + + %define __ALIGN_32BIT_1B__ 0x90 + %define __ALIGN_32BIT_2B__ 0x66,0x90 + %define __ALIGN_32BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_32BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_32BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_32BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_32BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_32BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + + %define __ALIGN_64BIT_1B__ 0x90 + %define __ALIGN_64BIT_2B__ 0x66,0x90 + %define __ALIGN_64BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_64BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_64BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_64BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + %elifidni %1,k7 + %define __ALIGN_16BIT_1B__ 0x90 + %define __ALIGN_16BIT_2B__ 0x66,0x90 + %define __ALIGN_16BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_16BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_16BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_16BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + + %define __ALIGN_32BIT_1B__ 0x90 + %define __ALIGN_32BIT_2B__ 0x8b,0xc0 + %define __ALIGN_32BIT_3B__ 0x8d,0x04,0x20 + %define __ALIGN_32BIT_4B__ 0x8d,0x44,0x20,0x00 + %define __ALIGN_32BIT_5B__ 0x8d,0x44,0x20,0x00,0x90 + %define __ALIGN_32BIT_6B__ 0x8d,0x80,0x00,0x00,0x00,0x00 + %define __ALIGN_32BIT_7B__ 0x8d,0x04,0x05,0x00,0x00,0x00,0x00 + %undef __ALIGN_32BIT_8B__ + + %define __ALIGN_64BIT_1B__ 0x90 + %define __ALIGN_64BIT_2B__ 0x66,0x90 + %define __ALIGN_64BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_64BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_64BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_64BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_64BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + %elifidni %1,p6 + %define __ALIGN_16BIT_1B__ 0x90 + %define __ALIGN_16BIT_2B__ 0x66,0x90 + %define __ALIGN_16BIT_3B__ 0x66,0x66,0x90 + %define __ALIGN_16BIT_4B__ 0x66,0x66,0x66,0x90 + %define __ALIGN_16BIT_5B__ 0x66,0x66,0x90,0x66,0x90 + %define __ALIGN_16BIT_6B__ 0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_7B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x90 + %define __ALIGN_16BIT_8B__ 0x66,0x66,0x66,0x90,0x66,0x66,0x66,0x90 + + %define __ALIGN_32BIT_1B__ 0x90 + %define __ALIGN_32BIT_2B__ 0x66,0x90 + %define __ALIGN_32BIT_3B__ 0x0f,0x1f,0x00 + %define __ALIGN_32BIT_4B__ 0x0f,0x1f,0x40,0x00 + %define __ALIGN_32BIT_5B__ 0x0f,0x1f,0x44,0x00,0x00 + %define __ALIGN_32BIT_6B__ 0x66,0x0f,0x1f,0x44,0x00,0x00 + %define __ALIGN_32BIT_7B__ 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 + %define __ALIGN_32BIT_8B__ 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 + + %define __ALIGN_64BIT_1B__ 0x90 + %define __ALIGN_64BIT_2B__ 0x66,0x90 + %define __ALIGN_64BIT_3B__ 0x0f,0x1f,0x00 + %define __ALIGN_64BIT_4B__ 0x0f,0x1f,0x40,0x00 + %define __ALIGN_64BIT_5B__ 0x0f,0x1f,0x44,0x00,0x00 + %define __ALIGN_64BIT_6B__ 0x66,0x0f,0x1f,0x44,0x00,0x00 + %define __ALIGN_64BIT_7B__ 0x0f,0x1f,0x80,0x00,0x00,0x00,0x00 + %define __ALIGN_64BIT_8B__ 0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00 + %else + %error unknown alignment mode: %1 + %endif + %xdefine __ALIGNMODE__ %1,__ALIGN_JMP_THRESHOLD__ +%endmacro + +%unimacro align 1-2+.nolist +%imacro align 1-2+.nolist + %ifnempty %2 + times ($$-$) % (%1) %2 + %else + %push + %assign %$pad ($$-$) % %1 + %if %$pad >= __ALIGN_JMP_THRESHOLD__ + jmp %%end + ; We can't re-use %$pad here as $ will have changed! + times ($$-$) % %1 db 90h +%%end: + %else + %if __BITS__ == 16 + %ifdef __ALIGN_16BIT_8B__ + %rep %$pad / 8 + db __ALIGN_16BIT_8B__ + %endrep + %assign %$pad %$pad % 8 + %else + %rep %$pad / 7 + db __ALIGN_16BIT_7B__ + %endrep + %assign %$pad %$pad % 7 + %endif + %if %$pad == 1 + db __ALIGN_16BIT_1B__ + %elif %$pad == 2 + db __ALIGN_16BIT_2B__ + %elif %$pad == 3 + db __ALIGN_16BIT_3B__ + %elif %$pad == 4 + db __ALIGN_16BIT_4B__ + %elif %$pad == 5 + db __ALIGN_16BIT_5B__ + %elif %$pad == 6 + db __ALIGN_16BIT_6B__ + %elif %$pad == 7 + db __ALIGN_16BIT_7B__ + %endif + %elif __BITS__ == 32 + %ifdef __ALIGN_32BIT_8B__ + %rep %$pad / 8 + db __ALIGN_32BIT_8B__ + %endrep + %assign %$pad %$pad % 8 + %else + %rep %$pad / 7 + db __ALIGN_32BIT_7B__ + %endrep + %assign %$pad %$pad % 7 + %endif + %if %$pad == 1 + db __ALIGN_32BIT_1B__ + %elif %$pad == 2 + db __ALIGN_32BIT_2B__ + %elif %$pad == 3 + db __ALIGN_32BIT_3B__ + %elif %$pad == 4 + db __ALIGN_32BIT_4B__ + %elif %$pad == 5 + db __ALIGN_32BIT_5B__ + %elif %$pad == 6 + db __ALIGN_32BIT_6B__ + %elif %$pad == 7 + db __ALIGN_32BIT_7B__ + %endif + %elif __BITS__ == 64 + %ifdef __ALIGN_64BIT_8B__ + %rep %$pad / 8 + db __ALIGN_64BIT_8B__ + %endrep + %assign %$pad %$pad % 8 + %else + %rep %$pad / 7 + db __ALIGN_64BIT_7B__ + %endrep + %assign %$pad %$pad % 7 + %endif + %if %$pad == 1 + db __ALIGN_64BIT_1B__ + %elif %$pad == 2 + db __ALIGN_64BIT_2B__ + %elif %$pad == 3 + db __ALIGN_64BIT_3B__ + %elif %$pad == 4 + db __ALIGN_64BIT_4B__ + %elif %$pad == 5 + db __ALIGN_64BIT_5B__ + %elif %$pad == 6 + db __ALIGN_64BIT_6B__ + %elif %$pad == 7 + db __ALIGN_64BIT_7B__ + %endif + %else + %error "Invalid __BITS__ value" + %endif + %endif + %pop + %endif +%endmacro + + alignmode generic diff --git a/test/smartalign.asm b/test/smartalign.asm new file mode 100644 index 00000000..65bdfcf4 --- /dev/null +++ b/test/smartalign.asm @@ -0,0 +1,23 @@ +%use smartalign + + bits 32 + + alignmode nop + add ax,ax + align 16 + + alignmode generic + add ax,ax + align 16 + + alignmode k7 + add ax,ax + align 16 + + alignmode k8 + add ax,ax + align 16 + + alignmode p6 + add ax,ax + align 16