/**
 * Copyright 2022 University of Adelaide
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*test assemblyline with register optimization disabled*/
#include <assemblyline.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char MOV_RI[] = "mov rax, 0x2\n"
                      "mov rax, 0x7f\n"
                      "mov rax, 0x80\n"
                      "mov rax, 0x80\n"
                      "mov rax, 0xff\n"
                      "mov rax, 0x7ff\n"
                      "mov eax, 0x2\n"
                      "mov eax, 0x7f\n"
                      "mov eax, 0x80\n"
                      "mov eax, 0x80\n"
                      "mov eax, 0xff\n"
                      "mov eax, 0x7ff\n"
                      "mov rax, 0x7fffffff\n"
                      "mov rax, 0x8fffffff\n"
                      "mov r13, 0x80000000\n"
                      "mov rax, 0xffffffff\n"
                      "mov rax, 0x7fffffffff\n"
                      "mov rax, 0xafffffffff\n"
                      "mov rax, 0xffffffff0000000e\n"
                      "mov rax, 0xff0fffff0000000e\n"
                      "mov rax, 0xffffffff000000ee\n"
                      "mov rax, 0xffffffff00000eee\n"
                      "mov rax, 0xffffffff000eeeee\n"
                      "mov rax, 0xffffffff00eeeeee\n"
                      "mov rax, 0xffffffff0eeeeeee\n"
                      "mov rax, 0xffffffffe0000000\n"
                      "mov rax, 0xfffffffff0000001\n"
                      "mov rax, 0xffffffff80000001\n"
                      "mov rax, 0xffffffffe0000001\n"
                      "mov rax, 0xffffffff72000001\n"
                      "mov rax, 0xffffffff60100001\n"
                      "mov rax, 0xffffffff500d0001\n"
                      "mov rax, 0xffffffff4000d001\n"
                      "mov rax, 0xffffffff30000d01\n"
                      "mov rax, 0xffffffff200000d1\n"
                      "mov rax, 0xffffffff10000001\n"
                      "mov rax, 0xffffffff01111111\n"
                      "mov rax, 0xfffffffef0000000\n"
                      "mov rax, 0xffffffffeeeeeeee\n"
                      "mov rax, 0xfffffeeeeeeeeeee\n"
                      "mov rax, 0xfffff77777777777\n"
                      "mov rax, 0xfffff22222222222\n"
                      "mov rax, 0xf000000000000001\n"
                      "mov rax, 0xffffffffffffffff\n"
                      "mov rax, -0x1\n"
                      "mov rax, -0x2\n"
                      "mov rsi, 0x2\n"
                      "mov rsi, 0x7f\n"
                      "mov rsi, 0x80\n"
                      "mov rsi, 0x80\n"
                      "mov rsi, 0xff\n"
                      "mov rsi, 0x7ff\n"
                      "mov esi, 0x2\n"
                      "mov esi, 0x7f\n"
                      "mov esi, 0x80\n"
                      "mov esi, 0x80\n"
                      "mov esi, 0xff\n"
                      "mov esi, 0x7ff\n"
                      "mov rsi, 0x7fffffff\n"
                      "mov rsi, 0x8fffffff\n"
                      "mov rsi, 0xffffffff\n"
                      "mov rsi, 0x7fffffffff\n"
                      "mov rsi, 0xafffffffff\n"
                      "mov rsi, 0xfffffeeeeeeeeeee\n"
                      "mov rsi, 0xffffffffeeeeeeee\n"
                      "mov rsi, -0x2\n"
                      "mov rsi, 0x2\n"
                      "mov rsi, 0x7f\n"
                      "mov rsi, 0x80\n"
                      "mov rsi, 0x80\n"
                      "mov rsi, 0xff\n"
                      "mov rsi, 0x7ff\n"
                      "mov esi, 0x2\n"
                      "mov esi, 0x7f\n"
                      "mov esi, 0x80\n"
                      "mov esi, 0x80\n"
                      "mov esi, 0xff\n"
                      "mov esi, 0x7ff\n"
                      "mov rsi, 0x7fffffff\n"
                      "mov rsi, 0x8fffffff\n"
                      "mov rsi, 0xffffffff\n"
                      "mov rsi, 0x7fffffffff\n"
                      "mov rsi, 0xafffffffff\n"
                      "mov rsi, 0xfffffeeeeeeeeeee\n"
                      "mov rsi, 0xffffffffeeeeeeee\n"
                      "mov rsi, -0x2\n"
                      "mov r13, 0x2\n"
                      "mov r13, 0x7f\n"
                      "mov r13, 0x80\n"
                      "mov r13, 0x80\n"
                      "mov r13, 0xff\n"
                      "mov r13, 0x7ff\n"
                      "mov r13d, 0x2\n"
                      "mov r13d, 0x7f\n"
                      "mov r13d, 0x80\n"
                      "mov r13d, 0x80\n"
                      "mov r13d, 0xff\n"
                      "mov r13d, 0x7ff\n"
                      "mov r13, 0x7fffffff\n"
                      "mov r13, 0x8fffffff\n"
                      "mov r13, 0xffffffff\n"
                      "mov r13, 0x7fffffffff\n"
                      "mov r13, 0xafffffffff\n"
                      "mov r13, 0xfffffeeeeeeeeeee\n"
                      "mov r13, 0xffffffffeeeeeeee\n"
                      "mov r13, -0x2\n"
                      "mov r15, 0x2\n"
                      "mov r15, 0x7f\n"
                      "mov r15, 0x80\n"
                      "mov r15, 0x80\n"
                      "mov r15, 0xff\n"
                      "mov r15, 0x7ff\n"
                      "mov r15w, 0x2\n"
                      "mov r15w, 0x7f\n"
                      "mov r15w, 0x80\n"
                      "mov r15w, 0x80\n"
                      "mov r15w, 0xff\n"
                      "mov r15w, 0x7ff\n"
                      "mov r15, 0x7fffffff\n"
                      "mov r15, 0x8fffffff\n"
                      "mov r15, 0xffffffff\n"
                      "mov r15, 0x7fffffffff\n"
                      "mov r15, 0xafffffffff\n"
                      "mov r15, 0xfffffeeeeeeeeeee\n"
                      "mov r15, 0xffffffffeeeeeeee\n"
                      "mov r15, -0x2\n"
                      "mov r15b, -0x2\n"
                      "mov r15b, 0x2\n"
                      "mov r15b, 0x7f\n"
                      "mov r15b, 0x80\n"
                      "mov r15b, 0x80\n"
                      "mov r15b, 0xff\n"
                      "mov rsi, -0x1\n"
                      "mov rbp, -0x2efd9f53\n"
                      "mov rbp, -0x2efa9f53\n"
                      "mov rbp, 0x2efa\n"
                      "mov r8, -0x2\n"
                      "mov r9, -0x2\n"
                      "mov r10, -0x2\n"
                      "mov r10b, -0x2\n"
                      "mov r11b, -0x2\n"
                      "mov r12b, -0x2\n"
                      "mov al, -0x2\n"
                      "mov al, -0x1\n"
                      "mov al, 0x1\n"
                      "mov cl, -0x2\n"
                      "mov cl, -0x1\n"
                      "mov cl, 0x1\n"
                      "mov ax, -0x2\n"
                      "mov ax, -0x1\n"
                      "mov ax, 0x1\n"
                      "mov cx, -0x2efd\n"
                      "mov cx, -0x2efa\n"
                      "mov cx, 0x2efa\n"
                      "mov si, -0x2efd\n"
                      "mov si, -0x2efa\n"
                      "mov si, 0x2efa\n"
                      "mov rcx, -0x2efd\n"
                      "mov rcx, -0x2efa\n"
                      "mov rcx, 0x2efa\n"
                      "mov rsi, -0x2efd\n"
                      "mov rsi, -0x2efa\n"
                      "mov rsi, 0x2efa\n"
                      "mov rcx, -0x2efdeeeeee\n"
                      "mov rcx, -0x2efaeeeeee\n"
                      "mov rcx, 0x2efaeeeee\n"
                      "mov rsi, -0x2efdeeee\n"
                      "mov rsi, -0x2efaeee\n"
                      "mov rsi, 0x2efaeeeee";

// obtained from https://defuse.ca/online-x86-assembler.html
const uint8_t MOV_RI_CODE[] = {
    0x48, 0xC7, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0, 0x7F, 0x00,
    0x00, 0x00, 0x48, 0xC7, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0,
    0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x48,
    0xC7, 0xC0, 0xFF, 0x07, 0x00, 0x00, 0xB8, 0x02, 0x00, 0x00, 0x00, 0xB8,
    0x7F, 0x00, 0x00, 0x00, 0xB8, 0x80, 0x00, 0x00, 0x00, 0xB8, 0x80, 0x00,
    0x00, 0x00, 0xB8, 0xFF, 0x00, 0x00, 0x00, 0xB8, 0xFF, 0x07, 0x00, 0x00,
    0x48, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0x7F, 0x48, 0xB8, 0xFF, 0xFF, 0xFF,
    0x8F, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBD, 0x00, 0x00, 0x00, 0x80, 0x00,
    0x00, 0x00, 0x00, 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
    0x00, 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x48,
    0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x0E,
    0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x0E, 0x00, 0x00,
    0x00, 0xFF, 0xFF, 0x0F, 0xFF, 0x48, 0xB8, 0xEE, 0x00, 0x00, 0x00, 0xFF,
    0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0xEE, 0x0E, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
    0xFF, 0x48, 0xB8, 0xEE, 0xEE, 0x0E, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
    0xB8, 0xEE, 0xEE, 0xEE, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0xEE,
    0xEE, 0xEE, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xC7, 0xC0, 0x00, 0x00,
    0x00, 0xE0, 0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0xF0, 0x48, 0xC7, 0xC0,
    0x01, 0x00, 0x00, 0x80, 0x48, 0xC7, 0xC0, 0x01, 0x00, 0x00, 0xE0, 0x48,
    0xB8, 0x01, 0x00, 0x00, 0x72, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x01,
    0x00, 0x10, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x01, 0x00, 0x0D,
    0x50, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x01, 0xD0, 0x00, 0x40, 0xFF,
    0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x01, 0x0D, 0x00, 0x30, 0xFF, 0xFF, 0xFF,
    0xFF, 0x48, 0xB8, 0xD1, 0x00, 0x00, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
    0xB8, 0x01, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x11,
    0x11, 0x11, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xB8, 0x00, 0x00, 0x00,
    0xF0, 0xFE, 0xFF, 0xFF, 0xFF, 0x48, 0xC7, 0xC0, 0xEE, 0xEE, 0xEE, 0xEE,
    0x48, 0xB8, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF, 0xFF, 0x48, 0xB8,
    0x77, 0x77, 0x77, 0x77, 0x77, 0xF7, 0xFF, 0xFF, 0x48, 0xB8, 0x22, 0x22,
    0x22, 0x22, 0x22, 0xF2, 0xFF, 0xFF, 0x48, 0xB8, 0x01, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xF0, 0x48, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x48,
    0xC7, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xC7, 0xC0, 0xFE, 0xFF, 0xFF,
    0xFF, 0x48, 0xC7, 0xC6, 0x02, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0x7F,
    0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0x80, 0x00, 0x00, 0x00, 0x48, 0xC7,
    0xC6, 0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0xFF, 0x00, 0x00, 0x00,
    0x48, 0xC7, 0xC6, 0xFF, 0x07, 0x00, 0x00, 0xBE, 0x02, 0x00, 0x00, 0x00,
    0xBE, 0x7F, 0x00, 0x00, 0x00, 0xBE, 0x80, 0x00, 0x00, 0x00, 0xBE, 0x80,
    0x00, 0x00, 0x00, 0xBE, 0xFF, 0x00, 0x00, 0x00, 0xBE, 0xFF, 0x07, 0x00,
    0x00, 0x48, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F, 0x48, 0xBE, 0xFF, 0xFF,
    0xFF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF,
    0x00, 0x00, 0x00, 0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00,
    0x00, 0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x00, 0x00, 0x00,
    0x48, 0xBE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF, 0xFF, 0x48, 0xC7,
    0xC6, 0xEE, 0xEE, 0xEE, 0xEE, 0x48, 0xC7, 0xC6, 0xFE, 0xFF, 0xFF, 0xFF,
    0x48, 0xC7, 0xC6, 0x02, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0x7F, 0x00,
    0x00, 0x00, 0x48, 0xC7, 0xC6, 0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6,
    0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0xFF, 0x00, 0x00, 0x00, 0x48,
    0xC7, 0xC6, 0xFF, 0x07, 0x00, 0x00, 0xBE, 0x02, 0x00, 0x00, 0x00, 0xBE,
    0x7F, 0x00, 0x00, 0x00, 0xBE, 0x80, 0x00, 0x00, 0x00, 0xBE, 0x80, 0x00,
    0x00, 0x00, 0xBE, 0xFF, 0x00, 0x00, 0x00, 0xBE, 0xFF, 0x07, 0x00, 0x00,
    0x48, 0xC7, 0xC6, 0xFF, 0xFF, 0xFF, 0x7F, 0x48, 0xBE, 0xFF, 0xFF, 0xFF,
    0x8F, 0x00, 0x00, 0x00, 0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
    0x00, 0x00, 0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0x00,
    0x00, 0x48, 0xBE, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF, 0x00, 0x00, 0x00, 0x48,
    0xBE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF, 0xFF, 0x48, 0xC7, 0xC6,
    0xEE, 0xEE, 0xEE, 0xEE, 0x48, 0xC7, 0xC6, 0xFE, 0xFF, 0xFF, 0xFF, 0x49,
    0xC7, 0xC5, 0x02, 0x00, 0x00, 0x00, 0x49, 0xC7, 0xC5, 0x7F, 0x00, 0x00,
    0x00, 0x49, 0xC7, 0xC5, 0x80, 0x00, 0x00, 0x00, 0x49, 0xC7, 0xC5, 0x80,
    0x00, 0x00, 0x00, 0x49, 0xC7, 0xC5, 0xFF, 0x00, 0x00, 0x00, 0x49, 0xC7,
    0xC5, 0xFF, 0x07, 0x00, 0x00, 0x41, 0xBD, 0x02, 0x00, 0x00, 0x00, 0x41,
    0xBD, 0x7F, 0x00, 0x00, 0x00, 0x41, 0xBD, 0x80, 0x00, 0x00, 0x00, 0x41,
    0xBD, 0x80, 0x00, 0x00, 0x00, 0x41, 0xBD, 0xFF, 0x00, 0x00, 0x00, 0x41,
    0xBD, 0xFF, 0x07, 0x00, 0x00, 0x49, 0xC7, 0xC5, 0xFF, 0xFF, 0xFF, 0x7F,
    0x49, 0xBD, 0xFF, 0xFF, 0xFF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBD,
    0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBD, 0xFF, 0xFF,
    0xFF, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x49, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF,
    0xAF, 0x00, 0x00, 0x00, 0x49, 0xBD, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE,
    0xFF, 0xFF, 0x49, 0xC7, 0xC5, 0xEE, 0xEE, 0xEE, 0xEE, 0x49, 0xC7, 0xC5,
    0xFE, 0xFF, 0xFF, 0xFF, 0x49, 0xC7, 0xC7, 0x02, 0x00, 0x00, 0x00, 0x49,
    0xC7, 0xC7, 0x7F, 0x00, 0x00, 0x00, 0x49, 0xC7, 0xC7, 0x80, 0x00, 0x00,
    0x00, 0x49, 0xC7, 0xC7, 0x80, 0x00, 0x00, 0x00, 0x49, 0xC7, 0xC7, 0xFF,
    0x00, 0x00, 0x00, 0x49, 0xC7, 0xC7, 0xFF, 0x07, 0x00, 0x00, 0x66, 0x41,
    0xBF, 0x02, 0x00, 0x66, 0x41, 0xBF, 0x7F, 0x00, 0x66, 0x41, 0xBF, 0x80,
    0x00, 0x66, 0x41, 0xBF, 0x80, 0x00, 0x66, 0x41, 0xBF, 0xFF, 0x00, 0x66,
    0x41, 0xBF, 0xFF, 0x07, 0x49, 0xC7, 0xC7, 0xFF, 0xFF, 0xFF, 0x7F, 0x49,
    0xBF, 0xFF, 0xFF, 0xFF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBF, 0xFF,
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x49, 0xBF, 0xFF, 0xFF, 0xFF,
    0xFF, 0x7F, 0x00, 0x00, 0x00, 0x49, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAF,
    0x00, 0x00, 0x00, 0x49, 0xBF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xFE, 0xFF,
    0xFF, 0x49, 0xC7, 0xC7, 0xEE, 0xEE, 0xEE, 0xEE, 0x49, 0xC7, 0xC7, 0xFE,
    0xFF, 0xFF, 0xFF, 0x41, 0xB7, 0xFE, 0x41, 0xB7, 0x02, 0x41, 0xB7, 0x7F,
    0x41, 0xB7, 0x80, 0x41, 0xB7, 0x80, 0x41, 0xB7, 0xFF, 0x48, 0xC7, 0xC6,
    0xFF, 0xFF, 0xFF, 0xFF, 0x48, 0xC7, 0xC5, 0xAD, 0x60, 0x02, 0xD1, 0x48,
    0xC7, 0xC5, 0xAD, 0x60, 0x05, 0xD1, 0x48, 0xC7, 0xC5, 0xFA, 0x2E, 0x00,
    0x00, 0x49, 0xC7, 0xC0, 0xFE, 0xFF, 0xFF, 0xFF, 0x49, 0xC7, 0xC1, 0xFE,
    0xFF, 0xFF, 0xFF, 0x49, 0xC7, 0xC2, 0xFE, 0xFF, 0xFF, 0xFF, 0x41, 0xB2,
    0xFE, 0x41, 0xB3, 0xFE, 0x41, 0xB4, 0xFE, 0xB0, 0xFE, 0xB0, 0xFF, 0xB0,
    0x01, 0xB1, 0xFE, 0xB1, 0xFF, 0xB1, 0x01, 0x66, 0xB8, 0xFE, 0xFF, 0x66,
    0xB8, 0xFF, 0xFF, 0x66, 0xB8, 0x01, 0x00, 0x66, 0xB9, 0x03, 0xD1, 0x66,
    0xB9, 0x06, 0xD1, 0x66, 0xB9, 0xFA, 0x2E, 0x66, 0xBE, 0x03, 0xD1, 0x66,
    0xBE, 0x06, 0xD1, 0x66, 0xBE, 0xFA, 0x2E, 0x48, 0xC7, 0xC1, 0x03, 0xD1,
    0xFF, 0xFF, 0x48, 0xC7, 0xC1, 0x06, 0xD1, 0xFF, 0xFF, 0x48, 0xC7, 0xC1,
    0xFA, 0x2E, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0x03, 0xD1, 0xFF, 0xFF, 0x48,
    0xC7, 0xC6, 0x06, 0xD1, 0xFF, 0xFF, 0x48, 0xC7, 0xC6, 0xFA, 0x2E, 0x00,
    0x00, 0x48, 0xB9, 0x12, 0x11, 0x11, 0x02, 0xD1, 0xFF, 0xFF, 0xFF, 0x48,
    0xB9, 0x12, 0x11, 0x11, 0x05, 0xD1, 0xFF, 0xFF, 0xFF, 0x48, 0xB9, 0xEE,
    0xEE, 0xAE, 0xEF, 0x02, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC6, 0x12, 0x11,
    0x02, 0xD1, 0x48, 0xC7, 0xC6, 0x12, 0x51, 0x10, 0xFD, 0x48, 0xBE, 0xEE,
    0xEE, 0xAE, 0xEF, 0x02, 0x00, 0x00, 0x00};

// manually disable nasm style immediate handling via zero padding to 64-bits
const char MOV_MANUAL_RI[] = "mov rax, 0x0000000000000002\n"
                             "mov rax, 0x000000000000007f\n"
                             "mov rax, 0x0000000000000080\n"
                             "mov rax, 0x0000000000000080\n"
                             "mov rax, 0x00000000000000ff\n"
                             "mov rax, 0x00000000000007ff\n"
                             "mov rax, 0x000000007fffffff\n"
                             "mov rax, 0x000000008fffffff\n"
                             "mov r13, 0x0000000080000000\n"
                             "mov rax, 0x00000000ffffffff\n";

// assembled  MOV_MANUAL_RI obtained from
// https://defuse.ca/online-x86-assembler.html
const uint8_t MOV_MANUAL_RI_CODE[] = {
    0x48, 0xC7, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0, 0x7F, 0x00,
    0x00, 0x00, 0x48, 0xC7, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0,
    0x80, 0x00, 0x00, 0x00, 0x48, 0xC7, 0xC0, 0xFF, 0x00, 0x00, 0x00, 0x48,
    0xC7, 0xC0, 0xFF, 0x07, 0x00, 0x00, 0x48, 0xC7, 0xC0, 0xFF, 0xFF, 0xFF,
    0x7F, 0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x49,
    0xBD, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x48, 0xB8, 0xFF,
    0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00};

int check_machine_code(const uint8_t ptr[], const uint8_t code[], size_t len) {
  for (size_t i = 0; i < len; ++i)
    // compare assemblyline output against pre-assembled machine code
    if (ptr[i] != code[i])
      return EXIT_FAILURE;
  return EXIT_SUCCESS;
}

int main() {

  assemblyline_t al = asm_create_instance(NULL, 0);
  // ensure nasm style register size optimization is disabled
  asm_mov_imm(al, STRICT);

  if (asm_assemble_str(al, MOV_RI) == EXIT_FAILURE)
    return EXIT_FAILURE;

  uint8_t *ptr = asm_get_code(al);

  size_t len = sizeof(MOV_RI_CODE) / sizeof(MOV_RI_CODE[0]);
  if (check_machine_code(ptr, MOV_RI_CODE, len))
    return EXIT_FAILURE;

  asm_set_offset(al, 0);

  // allow manual enabling of nasm style register size optimization
  asm_mov_imm(al, SMART);

  if (asm_assemble_str(al, MOV_MANUAL_RI) == EXIT_FAILURE)
    return EXIT_FAILURE;

  ptr = asm_get_code(al);

  len = sizeof(MOV_MANUAL_RI_CODE) / sizeof(MOV_MANUAL_RI_CODE[0]);
  if (check_machine_code(ptr, MOV_MANUAL_RI_CODE, len))
    return EXIT_FAILURE;

  return EXIT_SUCCESS;
}
