Some thoughts about the implementation of this.
The strings used are tokens so they could be integer values:
/* global variables */
/* global strings for arch:sse/avx instructions to use */
//extern char *MOVE_SIMD_DWORD;
//extern char *MOVE_SIMD_QWORD;
...
#define MOVE_SIMD_DWORD (T_MOVD + (ModuleInfo.arch * (T_VMOVD - T_MOVD)))
#define MOVE_SIMD_QWORD (T_MOVQ + (ModuleInfo.arch * (T_VMOVQ - T_MOVQ)))
Assuming the distance is equal ModuleInfo.arch could be a fixed integer or byte value.
In assemble.c:
/* ARCH SSE/AVX specific instructions */
//char *MOVE_ALIGNED_FLOAT = "movaps";
//char *MOVE_ALIGNED_INT = "movdqa";
//char *MOVE_UNALIGNED_FLOAT = "movups";
//char *MOVE_UNALIGNED_INT = "movdqu";
//char *MOVE_SINGLE = "movss";
//char *MOVE_DOUBLE = "movsd";
//char *MOVE_SIMD_DWORD = "movd";
//char *MOVE_SIMD_QWORD = "movq";
ModulePassInit():
ModuleInfo.arch = Options.arch;
The cmdline.c will set the option so uasm a.asm -avx b.asm will apply to module b.
static void OPTQUAL Set_SSE(void)
{
Options.arch = FALSE;
//ModuleInfo.arch = ARCH_SSE;
//MODULEARCH = ARCH_SSE;
//strcpy(MOVE_ALIGNED_FLOAT, "movaps");
//strcpy(MOVE_ALIGNED_INT, "movdqa");
//strcpy(MOVE_UNALIGNED_FLOAT, "movups");
//strcpy(MOVE_UNALIGNED_INT, "movdqu");
//strcpy(MOVE_SINGLE, "movss");
//strcpy(MOVE_DOUBLE, "movsd");
//strcpy(MOVE_SIMD_DWORD, "movd");
//strcpy(MOVE_SIMD_QWORD, "movq");
}
static void OPTQUAL Set_AVX(void)
{
Options.arch = TRUE;
//ModuleInfo.arch = ARCH_AVX;
//MODULEARCH = ARCH_AVX;
//strcpy(MOVE_ALIGNED_FLOAT, "vmovaps");
//strcpy(MOVE_ALIGNED_INT, "vmovdqa");
//strcpy(MOVE_UNALIGNED_FLOAT, "vmovups");
//strcpy(MOVE_UNALIGNED_INT, "vmovdqu");
//strcpy(MOVE_SINGLE, "vmovss");
//strcpy(MOVE_DOUBLE, "vmovsd");
//strcpy(MOVE_SIMD_DWORD, "vmovd");
//strcpy(MOVE_SIMD_QWORD, "vmovq");
}
option.c changes the current module:
/* OPTION ARCH:SSE/AVX */
OPTFUNC( SetArch )
{
int i = *pi;
//struct asym *archSym = SymFind("@Arch");
if (tokenarray.token == T_ID) {
if (0 == _stricmp(tokenarray.string_ptr, "SSE")) {
//MODULEARCH = ARCH_SSE;
ModuleInfo.arch = FALSE;
//strcpy(MOVE_ALIGNED_FLOAT, "movaps");
//strcpy(MOVE_ALIGNED_INT, "movdqa");
//strcpy(MOVE_UNALIGNED_FLOAT, "movups");
//strcpy(MOVE_UNALIGNED_INT, "movdqu");
//strcpy(MOVE_SINGLE, "movss");
//strcpy(MOVE_DOUBLE, "movsd");
//strcpy(MOVE_SIMD_DWORD, "movd");
//strcpy(MOVE_SIMD_QWORD, "movq");
//archSym->value = ARCH_SSE;
}
else if (0 == _stricmp(tokenarray.string_ptr, "AVX")) {
//MODULEARCH = ARCH_AVX;
ModuleInfo.arch = TRUE;
//strcpy(MOVE_ALIGNED_FLOAT, "vmovaps");
//strcpy(MOVE_ALIGNED_INT, "vmovdqa");
//strcpy(MOVE_UNALIGNED_FLOAT, "vmovups");
//strcpy(MOVE_UNALIGNED_INT, "vmovdqu");
//strcpy(MOVE_SINGLE, "vmovss");
//strcpy(MOVE_DOUBLE, "vmovsd");
//strcpy(MOVE_SIMD_DWORD, "vmovd");
//strcpy(MOVE_SIMD_QWORD, "vmovq");
//archSym->value = ARCH_AVX;
}
invoke.c and other files using MOVE_ needs format %r:
AddLineQueueX(" %r %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);
//if (param->sym.mem_type == MT_REAL4)
// AddLineQueueX(" %s %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);
//else
// AddLineQueueX(" %s %r, %s", MOVE_ALIGNED_FLOAT, T_XMM0 + index, paramvalue);