debug = {
"COMM": "COMM %s\n",
"NOP": "NOP\n",
"IMM": "IMM %d\n",
"ADD": "ADD\n",
"SUB": "SUB\n",
"MUL": "MUL\n",
"DIV": "DIV\n",
"MOD": "MOD\n",
"NEG": "NEG\n",
"INCR": "INCR %d\n",
"DECR": "DECR %d\n",
"GT": "GT\n",
"GE": "GE\n",
"LT": "LT\n",
"LE": "LE\n",
"EQ": "EQ\n",
"NE": "NE\n",
"AND": "AND\n",
"OR": "OR\n",
"XOR": "XOR\n",
"NOT": "NOT\n",
"ROTL": "ROTL\n",
"ROTR": "ROTR\n",
"SHTL": "SHTL\n",
"SHTRU": "SHTRU\n",
"SHTRS": "SHTRS\n",
"LOCAL": "LOCAL %d\n",
"ADDR": "ADDR %s\n",
"LOCV": "LOCV %d\n",
"ADDRV": "ADDRV %s\n",
"LOCA": "LOCA %d\n",
"ADDRA": "ADDRA %s\n",
"LOAD": "LOAD\n",
"STORE": "STORE\n",
"LDCHR": "LDCHR\n",
"STCHR": "STCHR\n",
"LD16": "LD16\n",
"ST16": "ST16\n",
"ENTER": "ENTER %d\n",
"START": "START\n",
"ALLOC": "ALLOC\n",
"LEAVE": "LEAVE\n",
"TRASH": "TRASH %d\n",
"CALL": "CALL %s\n",
"RET": "RET\n",
"RETN": "RETN %d\n",
"BRANCH": "BRANCH\n",
"LEAP": "LEAP\n",
"JMP": "JMP %s\n",
"JZ": "JZ %s\n",
"JNZ": "JNZ %s\n",
"COPY": "COPY\n",
"SWAP": "SWAP\n",
"SP": "SP\n",
"PUSH": "PUSH\n",
"POP": "POP\n",
"I2D": "I2D\n",
"F2D": "F2D\n",
"D2I": "D2I\n",
"D2F": "D2F\n",
"DADD": "DADD\n",
"DSUB": "DSUB\n",
"DMUL": "DMUL\n",
"DDIV": "DDIV\n",
"DCMP": "DCMP\n",
"DNEG": "DNEG\n",
"LOAD2": "LOAD2\n",
"STORE2": "STORE2\n",
"COPY2": "COPY2\n",
"DPUSH": "DPUSH\n",
"DPOP": "DPOP\n",
"NIL": "NIL\n",
"BEGIN": "BEGIN %s\n",
"END": "END\n",
"TEXT": "TEXT\n",
"RODATA": "RODATA\n",
"DATA": "DATA\n",
"BSS": "BSS\n",
"ALIGN": "ALIGN\n",
"EXTRN": "EXTRN %s\n",
"COMMON": "COMMON %d\n",
"GLOBL": "GLOBL %s %s\n",
"LABEL": "LABEL %s\n",
"INTEGER": "INTEGER %d\n",
"SHORT": "SHORT %d\n",
"LONG": "LONG %ld\n",
"STR": "STR \"%s\"\n",
"CHAR": "CHAR 0x%2.2X\n",
"ID": "ID %s\n",
"BYTE": "BYTE %d\n",
"FLOAT": "FLOAT %e\n",
"DOUBLE": "DOUBLE %e\n",
"ULDCHR": "ULDCHR\n",
"ULD16": "ULD16\n",
"UDIV": "UDIV\n",
"UMOD": "UMOD\n",
"UGT": "UGT\n",
"UGE": "UGE\n",
"ULT": "ULT\n",
"ULE": "ULE\n",
"JEQ": "JEQ %s\n",
"JNE": "JNE %s\n",
"JGT": "JGT %s\n",
"JGE": "JGE %s\n",
"JLT": "JLT %s\n",
"JLE": "JLE %s\n",
"JUGT": "JUGT %s\n",
"JUGE": "JUGE %s\n",
"JULT": "JULT %s\n",
"JULE": "JULE %s\n",

"LD64": "LD64\n",
"ST64": "ST64\n",
"ULD64": "ULD64\n",

"ASM": "ASM %s\n",
"BB": "BB\n",
"WORD": 4,
"NONE":	":none",
"FUNC":	":function",
"OBJ":	":object",

"ARG1": " ",
"ARG2": " ",
"ARG3": " ",
"ARG4": " ",
"ARG5": " ",
"ARG6": " ",
"ARG1D": " ",
"ARG2D": " ",
"ARG3D": " ",
"ARG4D": " ",
"ARG5D": " ",
"ARG6D": " ",
}
debug['LD32'] = debug['LOAD']
debug['ST32'] = debug['STORE']
debug['ULD32'] = debug['LOAD']
debug['CONST'] = debug['INTEGER']

num = {
"COMM":	1,
"NOP":	2,
"IMM":	3,
"ADD":	4,
"SUB":	5,
"MUL":	6,
"DIV":	7,
"MOD":	8,
"NEG":	9,
"INCR":	10,
"DECR":	11,
"GT":		12,
"GE":		13,
"LT":		14,
"LE":		15,
"EQ":		16,
"NE":		17,
"AND":	18,
"OR":		19,
"XOR":	20,
"NOT":	21,
"ROTL":	22,
"ROTR":	23,
"SHTL":	24,
"SHTRU":	25,
"SHTRS":	26,
"LOCAL":	27,
"ADDR":	28,
"LOCV":	29,
"ADDRV":	30,
"LOCA":	31,
"ADDRA":	32,
"LOAD":	33,
"STORE":	34,
"LDCHR":	35,
"STCHR":	36,
"LD16":	37,
"ST16":	38,
"ENTER":	39,
"START":	40,
"ALLOC":	41,
"LEAVE":	42,
"TRASH":	43,
"CALL":	44,
"RET":	45,
"RETN":	46,
"BRANCH":	47,
"LEAP":	48,
"JMP":	49,
"JZ":		50,
"JNZ":	51,
"COPY":	52,
"SWAP":	53,
"SP":		54,
"PUSH":	55,
"POP":	56,
"I2D":	57,
"F2D":	58,
"D2I":	59,
"D2F":	60,
"DADD":	61,
"DSUB":	62,
"DMUL":	63,
"DDIV":	64,
"DCMP":	65,
"DNEG":	66,
"LOAD2":	67,
"STORE2":	68,
"COPY2":	69,
"DPUSH":	70,
"DPOP":	71,
"NIL":	72,
"BEGIN":	73,
"END":	74,
"TEXT":	75,
"RODATA":	76,
"DATA":	77,
"BSS":	78,
"ALIGN":	79,
"EXTRN":	80,
"COMMON":	81,
"GLOBL":	82,
"LABEL":	83,
"INTEGER":	84,
"SHORT":	85,
"LONG":	86,
"STR":	87,
"CHAR":	88,
"ID":		89,
"BYTE":	90,
"FLOAT":	91,
"DOUBLE":	92,
"ULDCHR":	93,
"ULD16":	94,
"UDIV":	95,
"UMOD":	96,
"UGT":	97,
"UGE":	98,
"ULT":	99,
"ULE":	100,
"JEQ":	101,
"JNE":	102,
"JGT":	103,
"JGE":	104,
"JLT":	105,
"JLE":	106,
"JUGT":	107,
"JUGE":	108,
"JULT":	109,
"JULE":	110,

"LD64":	111,
"ST64":	112,
"ULD64":	113,
"LD32":	114,
"ST32":	115,
"ULD32":	116,

"ASM":	118,
"BB":		119,

"R0":		0x40,
"R1":		0x20,
"R2":		0x10,
"Rreg":	0x0,
"Rint":	0x1,
"Rstr":	0x2,
"Rdbl":	0x3,
"Rlng":	0x4,
"WORD": 	4,
"NONE":	0,
"FUNC":	120,
"OBJ":	121,

"ARG1": " ",
"ARG2": " ",
"ARG3": " ",
"ARG4": " ",
"ARG5": " ",
"ARG6": " ",
"ARG1D": " ",
"ARG2D": " ",
"ARG3D": " ",
"ARG4D": " ",
"ARG5D": " ",
"ARG6D": " ",
}
num['CONST'] = num['INTEGER']

names = ( 0, "comm", "nop", "imm", "add", "sub", "mul", "div",
	"mod", "neg", "incr", "decr", "gt", "ge", "lt", "le", "eq", "ne",
	"and", "or", "xor", "not", "rotl", "rotr", "shtl", "shtru", "shtrs",
	"local", "addr", "locv", "addrv", "loca", "addra", "load", "store",
	"ldchr", "stchr", "ld16", "st16", "enter", "start", "alloc", "leave",
	"trash", "call", "ret", "retn", "branch", "leap", "jmp", "jz", "jnz",
	"copy", "swap", "sp", "push", "pop", "i2d", "f2d", "d2i", "d2f",
	"dadd", "dsub", "dmul", "ddiv", "dcmp", "dneg", "load2", "store2",
	"copy2", "dpush", "dpop", "nil", "begin", "end", "text", "rodata",
	"data", "bss", "align", "extrn", "common", "globl", "label",
	"integer", "short", "long", "str", "char", "id", "byte", "float",
	"double", "uldchr", "uld16", "udiv", "umod", "ugt", "uge", "ult",
	"ule", "jeq", "jne", "jgt", "jge", "jlt", "jle", "jugt", "juge",
	"jult", "jule", "ld64", "st64", "uld64", "ld32", "st32", "uld32",
	0, "asm", "BB", "func", "obj" )

arm = {
"COMM": "@ COMM %s\n",
"NOP": "@ NOP\n\tnop\n",
"IMM": "@ IMM\n\tldr\tr0, =%d\n\tpush\t{r0}\n",
"ADD": "@ ADD\n\tpop\t{r0,r1}\n\tadd\tr0, r1, r0\n\tpush\t{r0}\n",
"SUB": "@ SUB\n\tpop\t{r0,r1}\n\tsub\tr0, r1, r0\n\tpush\t{r0}\n",
"MUL": "@ MUL\n\tpop\t{r0,r1}\n\tmul\tr0, r1, r0\n\tpush\t{r0}\n",
"DIV": "@ DIV\n\tpop\t{r1}\n\tpop\t{r0}\n\tbl\t_div\n\tpush\t{r0}\n",
"MOD": "@ MOD\n\tpop\t{r1}\n\tpop\t{r0}\n\tbl\t_mod\n\tpush\t{r0}\n",
"NEG": "@ NEG\n\tpop\t{r0}\n\trsb\tr0, r0, #0\n\tpush\t{r0}\n",
"INCR": "@ INCR\n\tpop\t{r0}\n\tldr\tr1, [r0]\n\tldr\tr2, =%d\n\tadd\tr1, r1, r2\n\tstr\tr1, [r0]\n",
"DECR": "@ DECR\n\tpop\t{r0}\n\tldr\tr1, [r0]\n\tldr\tr2, =%d\n\tsub\tr1, r1, r2\n\tstr\tr1, [r0]\n",
"GT": "@ GT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovgt\tr0, #1\n\tmovle\tr0, #0\n\tpush\t{r0}\n",
"GE": "@ GE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovge\tr0, #1\n\tmovlt\tr0, #0\n\tpush\t{r0}\n",
"LT": "@ LT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovlt\tr0, #1\n\tmovge\tr0, #0\n\tpush\t{r0}\n",
"LE": "@ LE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovle\tr0, #1\n\tmovgt\tr0, #0\n\tpush\t{r0}\n",
"EQ": "@ EQ\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmoveq\tr0, #1\n\tmovne\tr0, #0\n\tpush\t{r0}\n",
"NE": "@ NE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovne\tr0, #1\n\tmoveq\tr0, #0\n\tpush\t{r0}\n",
"AND": "@ AND\n\tpop\t{r0,r1}\n\tand\tr0, r0, r1\n\tpush\t{r0}\n",
"OR": "@ OR\n\tpop\t{r0,r1}\n\torr\tr0, r0, r1\n\tpush\t{r0}\n",
"XOR": "@ XOR\n\tpop\t{r0,r1}\n\teor\tr0, r0, r1\n\tpush\t{r0}\n",
"NOT": "@ NOT\n\tpop\t{r0}\n\tmvn\tr0, r0\n\tpush\t{r0}\n",
"ROTL": "@ ROTL\n\tpop\t{r0,r1}\n\trsb\tr0, r0, #32\n\tmov\tr0, r1, ror r0\n\tpush\t{r0}\n",
"ROTR": "@ ROTR\n\tpop\t{r0,r1}\n\tmov\tr0, r1, ror r0\n\tpush\t{r0}\n",
"SHTL": "@ SHTL\n\tpop\t{r0,r1}\n\tmov\tr0, r1, lsl r0\n\tpush\t{r0}\n",
"SHTRU": "@ SHTRU\n\tpop\t{r0,r1}\n\tmov\tr0, r1, lsr r0\n\tpush\t{r0}\n",
"SHTRS": "@ SHTRS\n\tpop\t{r0,r1}\n\tmov\tr0, r1, asr r0\n\tpush\t{r0}\n",
"LOCAL": "@ LOCAL\n\tldr\tr0, =%d\n\tadd\tr0, fp, r0\n\tpush\t{r0}\n",
"ADDR": "@ ADDR\n\tldr\tr0, =%s\n\tpush\t{r0}\n",
"LOCV": "@ LOCV\n\tldr\tr0, =%d\n\tldr\tr0, [fp, r0]\n\tpush\t{r0}\n",
"ADDRV": "@ ADDRV\n\tldr\tr0, =%s\n\tldr\tr0, [r0]\n\tpush\t{r0}\n",
"LOCA": "@ LOCA\n\tpop\t{r1}\n\tldr\tr0, =%d\n\tstr\tr1, [fp, r0]\n",
"ADDRA": "@ ADDRA\n\tpop\t{r1}\n\tldr\tr0, =%s\n\tstr\tr1, [r0]\n",
"LOAD": "@ LOAD\n\tpop\t{r0}\n\tldr\tr0, [r0]\n\tpush\t{r0}\n",
"STORE": "@ STORE\n\tpop\t{r0,r1}\n\tstr\tr1, [r0]\n",
"LDCHR": "@ LDCHR\n\tpop\t{r0}\n\tldrsb\tr0, [r0]\n\tpush\t{r0}\n",
"STCHR": "@ STCHR\n\tpop\t{r0,r1}\n\tstrb\tr1, [r0]\n",
"LD16": "@ LD16\n\tpop\t{r0}\n\tldrsh\tr0, [r0]\n\tpush\t{r0}\n",
"ST16": "@ ST16\n\tpop\t{r0,r1}\n\tstrh\tr1, [r0]\n",
"ENTER": "@ ENTER\n\tpush\t{lr}\n\tpush\t{fp}\n\tmov\tfp, sp\n\tldr\tr0, =%d\n\tsub\tsp, sp, r0\n",
"START": "@ START\n\tpush\t{lr}\n\tpush\t{fp}\n\tmov\tfp, sp\n",
"ALLOC": "@ ALLOC\n\tpop\t{r0}\n\tsub\tsp, sp, r0\n",
"LEAVE": "@ LEAVE\n\tmov\tsp, fp\n\tpop\t{fp}\n",
"TRASH": "@ TRASH\n\tldr\tr2, =%d\n\tadd\tsp, sp, r2\n",
"CALL": "@ CALL\n\tbl\t%s\n",
"RET": "@ RET\n\tpop\t{pc}\n",
"RETN": "@ RETN\n\tpop\t{lr}\n\tldr\tr2, =%d\n\tadd\tsp, sp, r2\n\tbx\tlr\n",
"BRANCH": "@ BRANCH\n\tmov\trl, pc\n\tpop\t{pc}\n",
"LEAP": "@ LEAP\n\tpop\t{pc}\n",
"JMP": "@ JMP\n\tb\t%s\n",
"JZ": "@ JZ\n\tpop\t{r0}\n\tcmp\tr0, #0\n\tbeq\t%s\n",
"JNZ": "@ JNZ\n\tpop\t{r0}\n\tcmp\tr0, #0\n\tbne\t%s\n",
"COPY": "@ COPY\n\tpop\t{r0}\n\tpush\t{r0}\n\tpush\t{r0}\n",
"SWAP": "@ SWAP\n\tpop\t{r0,r1}\n\tpush\t{r0}\n\tpush\t{r1}\n",
"SP": "@ SP\n\tpush\t{sp}\n",
"PUSH": "@ PUSH\n\tpush\t{r0}\n",
"POP": "@ POP\n\tpop\t{r0}\n",
"I2D": "@ I2D\n\tpop\t{r0}\n\tbl\t_i2d\n\tpush\t{r0,r1}\n",
"F2D": "@ F2D\n\tpop\t{r0}\n\tbl\t_f2d\n\tpush\t{r0,r1}\n",
"D2I": "@ D2I\n\tpop\t{r0,r1}\n\tbl\t_d2i\n\tpush\t{r0}\n",
"D2F": "@ D2F\n\tpop\t{r0,r1}\n\tbl\t_d2f\n\tpush\t{r0}\n",
"DADD": "@ DADD\n\tpop\t{r0,r1,r2,r3}\n\tbl\t_dadd\n\tpush\t{r0,r1}\n",
"DSUB": "@ DSUB\n\tpop\t{r0,r1,r2,r3}\n\tbl\t_dsub\n\tpush\t{r0,r1}\n",
"DMUL": "@ DMUL\n\tpop\t{r0,r1,r2,r3}\n\tbl\t_dmul\n\tpush\t{r0,r1}\n",
"DDIV": "@ DDIV\n\tpop\t{r0,r1,r2,r3}\n\tbl\t_ddiv\n\tpush\t{r0,r1}\n",
"DCMP": "@ DCMP\n\tpop\t{r0,r1,r2,r3}\n\tbl\t_dcmp\n\tpush\t{r0}\n",
"DNEG": "@ DNEG\n\tpop\t{r0,r1}\n\tbl\t_dneg\n\tpush\t{r0,r1}\n",
"LOAD2": "@ LOAD2\n\tpop\t{r0}\n\tldr\tr1, [r0, #4]\n\tldr\tr0, [r0]\n\tpush\t{r0,r1}\n",
"STORE2": "@ STORE2\n\tpop\t{r0,r1,r2}\n\tstr\tr1, [r0]\n\tstr\tr2, [r0, #4]\n",
"COPY2": "@ COPY2\n\tldr\tr0, [sp, #4]\n\tpush\t{r0}\n\tldr\tr0, [sp, #4]\n\tpush\t{r0}\n",
"DPUSH": "@ DPUSH\n\tpush\t{r0,r1}\n",
"DPOP": "@ DPOP\n\tpop\t{r0,r1}\n",
"NIL": "@ NIL\n",
"BEGIN": "@ BEGIN\n\t.file \"%s\"\n",
"END": "@ END\n",
"TEXT": "@ TEXT\n.section\t.text\n",
"RODATA": "@ RODATA\n.section\t.rodata\n",
"DATA": "@ DATA\n.section\t.data\n",
"BSS": "@ BSS\n.section\t.bss\n",
"ALIGN": "@ ALIGN\n.align\t4\n",
"EXTRN": "@ EXTRN\n.extern\t%s\n",
"COMMON": "@ COMMON\n.comm\t%s,4\n",
"GLOBL": "@ GLOBL\n.global\t%s%s\n",
"LABEL": "@ LABEL\n%s:\n",
"INTEGER": "@ INTEGER\n\t.word\t%d\n",
"SHORT": "@ SHORT\n\t.short\t%d\n",
"LONG": "@ LONG\n\t.word\t%d\n\t.word\t%d\n",
"STR": "@ STR\n\t.asciz\t\"%s\"\n",
"CHAR": "@ CHAR\n\t.byte\t0x%2.2X\n",
"ID": "@ ID\n\t.word\t%s\n",
"BYTE": "@ BYTE\n\t.space\t%d\n",
"FLOAT": "@ FLOAT\n\t.float\t0f%g\n",
"DOUBLE": "@ DOUBLE\n\t.double\t0d%15.15e\n",
"ULDCHR": "@ ULDCHR\n\tpop\t{r0}\n\tldrb\tr0, [r0]\n\tpush\t{r0}\n",
"ULD16": "@ ULD16\n\tpop\t{r0}\n\tldrh\tr0, [r0]\n\tpush\t{r0}\n",
"UDIV": "@ UDIV\n\tpop\t{r1}\n\tpop\t{r0}\n\tbl\t_udiv\n\tpush\t{r0}\n",
"UMOD": "@ UMOD\n\tpop\t{r1}\n\tpop\t{r0}\n\tbl\t_umod\n\tpush\t{r0}\n",
"UGT": "@ UGT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovls\tr0, #1\n\tmovhi\tr0, #0\n\tpush\t{r0}\n",
"UGE": "@ UGE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovcc\tr0, #1\n\tmovcs\tr0, #0\n\tpush\t{r0}\n",
"ULT": "@ ULT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovcs\tr0, #1\n\tmovcc\tr0, #0\n\tpush\t{r0}\n",
"ULE": "@ ULE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tmovhi\tr0, #1\n\tmovls\tr0, #0\n\tpush\t{r0}\n",
"JEQ": "@ JEQ\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbeq\t%s\n",
"JNE": "@ JNE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbne\t%s\n",
"JGT": "@ JGT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbgt\t%s\n",
"JGE": "@ JGE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbge\t%s\n",
"JLT": "@ JLT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tblt\t%s\n",
"JLE": "@ JLE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tble\t%s\n",
"JUGT": "@ JUGT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbls\t%s\n",
"JUGE": "@ JUGE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbcc\t%s\n",
"JULT": "@ JULT\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbcs\t%s\n",
"JULE": "@ JULE\n\tpop\t{r0,r1}\n\tcmp\tr1, r0\n\tbhi\t%s\n",

"LD64": "@ LD64\n",
"ST64": "@ ST64\n",
"ULD64": "@ ULD64\n",

"ASM": "@ ASM\n\t%s\n",
"BB": "@ BB\n",

"ARG1":	"@ ARG1\n\tldr\tr0, [sp]\n",
"ARG2":	"@ ARG2\n\tldr\tr1, [sp,#4]\n",
"ARG3":	"@ ARG3\n\tldr\tr2, [sp,#8]\n",
"ARG4":	"@ ARG4\n\tldr\tr3, [sp,#12]\n",
"ARG1D":	"@ ARG1D\n\tldr\tr0, [sp]\n\tldr\tr1, [sp,#4]\n",
"ARG2D":	"@ ARG2D\n\tldr\tr0, [sp,#8]\n\tldr\tr1, [sp,#12]\n",
"WORD": 4,
"NONE":	"",		# unknown global label type
"FUNC":	" @function",	# should declare in .type
"OBJ":	"",

"ARG5": " ",
"ARG6": " ",
"ARG3D": " ",
"ARG4D": " ",
"ARG5D": " ",
"ARG6D": " ",
}

arm['LD32'] = arm['LOAD']
arm['ST32'] = arm['STORE']
arm['ULD32'] = arm['LOAD']
arm['CONST'] = arm['INTEGER']

amd64 = {
"COMM": "; COMM %s\n",
"NOP": "; NOP\n\tnop\n",
"IMM": "; IMM\n\tmov\trax, qword %ld\n\tpush\trax\n", # only MOVs accept 64-bit immediates
"ADD": "; ADD\n\tpop\trax\n\tadd\tqword [rsp], rax\n",
"SUB": "; SUB\n\tpop\trax\n\tsub\tqword [rsp], rax\n",
"MUL": "; MUL\n\tpop\trax\n\timul\tqword rax, [rsp]\n\tmov\t[rsp], rax\n",
"DIV": "; DIV\n\tpop\trcx\n\tpop\trax\n\tmov\trdx, rax\n\tsar\trdx, 63\n\tidiv\trcx\n\tpush\trax\n",
"MOD": "; MOD\n\tpop\trcx\n\tpop\trax\n\tmov\trdx, rax\n\tsar\trdx, 63\n\tidiv\trcx\n\tpush\trdx\n",
"NEG": "; NEG\n\tneg\tqword [rsp]\n",
"INCR": "; INCR\n\tpop\trax\n\tadd\tqword [rax], %d\n",
"DECR": "; DECR\n\tpop\trax\n\tsub\tqword [rax], %d\n",
"GT": "; GT\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetg\tcl\n\tmov\t[rsp], rcx\n",
"GE": "; GE\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetge\tcl\n\tmov\t[rsp], rcx\n",
"LT": "; LT\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetl\tcl\n\tmov\t[rsp], rcx\n",
"LE": "; LE\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetle\tcl\n\tmov\t[rsp], rcx\n",
"EQ": "; EQ\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsete\tcl\n\tmov\t[rsp], rcx\n",
"NE": "; NE\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetne\tcl\n\tmov\t[rsp], rcx\n",
"AND": "; AND\n\tpop\trax\n\tand\tqword [rsp], rax\n",
"OR": "; OR\n\tpop\trax\n\tor\tqword [rsp], rax\n",
"XOR": "; XOR\n\tpop\trax\n\txor\tqword [rsp], rax\n",
"NOT": "; NOT\n\tnot\tqword [rsp]\n",
"ROTL": "; ROTL\n\tpop\trcx\n\trol\tqword [rsp], cl\n",
"ROTR": "; ROTR\n\tpop\trcx\n\tror\tqword [rsp], cl\n",
"SHTL": "; SHTL\n\tpop\trcx\n\tsal\tqword [rsp], cl\n",
"SHTRU": "; SHTRU\n\tpop\trcx\n\tshr\tqword [rsp], cl\n",
"SHTRS": "; SHTRS\n\tpop\trcx\n\tsar\tqword [rsp], cl\n",
"LOCAL": "; LOCAL\n\tlea\trax, [rbp+%d]\n\tpush\trax\n",
"ADDR": "; ADDR\n\tmov\trax, $%s\n\tpush\trax\n",
"LOCV": "; LOCV\n\tpush\tqword [rbp+%d]\n",
"ADDRV": "; ADDRV\n\tmov\trax, [abs qword $%s]\n\tpush\trax\n",
"LOCA": "; LOCA\n\tpop\trax\n\tmov\t[rbp+%d], rax\n",
"ADDRA": "; ADDRA\n\tpop\trax\n\tmov\t[abs qword $%s], rax\n",
"LOAD": "; LOAD\n\tpop\trax\n\tpush\tqword [rax]\n",
"STORE": "; STORE\n\tpop\trcx\n\tpop\trax\n\tmov\t[rcx], rax\n",
"LDCHR": "; LDCHR\n\tpop\trcx\n\tmovsx\trax,byte [rcx]\n\tpush\trax\n",
"STCHR": "; STCHR\n\tpop\trcx\n\tpop\trax\n\tmov\t[rcx], al\n",
"LD16": "; LD16\n\tpop\trcx\n\tmovsx\trax,word [rcx]\n\tpush\trax\n",
"ST16": "; ST16\n\tpop\trcx\n\tpop\trax\n\tmov\t[rcx], ax\n",
"ENTER": "; ENTER\n\tpush\trbp\n\tmov\trbp, rsp\n\tsub\trsp, %d\n",
"START": "; START\n\tpush\trbp\n\tmov\trbp, rsp\n",
"ALLOC": "; ALLOC\n\tpop\trax\n\tsub\trsp, rax\n",
"LEAVE": "; LEAVE\n\tleave\n",
"TRASH": "; TRASH\n\tadd\trsp, %d\n",
"CALL": "; CALL\n\tcall\t$%s\n",
"RET": "; RET\n\tret\n",
"RETN": "; RETN\n\tret\t%d\n",
"BRANCH": "; BRANCH\n\tpop\trax\n\tcall\trax\n",
"LEAP": "; LEAP\n\tpop\trax\n\tjmp\trax\n",
"JMP": "; JMP\n\tjmp\t$%s\n",
"JZ": "; JZ\n\tpop\trax\n\tcmp\trax, byte 0\n\tje\tnear $%s\n",
"JNZ": "; JNZ\n\tpop\trax\n\tcmp\trax, byte 0\n\tjne\tnear $%s\n",
"COPY": "; COPY\n\tpush\tqword [rsp]\n",
"SWAP": "; SWAP\n\tpop\trax\n\tpop\trcx\n\tpush\trax\n\tmov\trax, rcx\n\tpush\trax\n",
"SP": "; SP\n\tpush\trsp\n",
"PUSH": "; PUSH\n\tpush\trax\n",
"POP": "; POP\n\tpop\trax\n",
"I2D": "; I2D\n\tfild\tqword [rsp]\n\tsub\trsp, byte 4\n\tfstp\tqword [rsp]\n",
"F2D": "; F2D\n\tfld\tqword [rsp]\n\tsub\trsp, byte 4\n\tfstp\tqword [rsp]\n",
"D2I": "; D2I\n\tfld\tqword [rsp]\n\tadd\trsp, byte 4\n\tfistp\tqword [rsp]\n",
"D2F": "; D2F\n\tfld\tqword [rsp]\n\tadd\trsp, byte 4\n\tfstp\tqword [rsp]\n",
"DADD": "; DADD\n\tfld\tqword [rsp]\n\tadd\trsp, byte 8\n\tfld\tqword [rsp]\n\tfaddp\tst1\n\tfstp\tqword [rsp]\n",
"DSUB": "; DSUB\n\tfld\tqword [rsp]\n\tadd\trsp, byte 8\n\tfld\tqword [rsp]\n\tfsubrp\tst1\n\tfstp\tqword [rsp]\n",
"DMUL": "; DMUL\n\tfld\tqword [rsp]\n\tadd\trsp, byte 8\n\tfld\tqword [rsp]\n\tfmulp\tst1\n\tfstp\tqword [rsp]\n",
"DDIV": "; DDIV\n\tfld\tqword [rsp]\n\tadd\trsp, byte 8\n\tfld\tqword [rsp]\n\tfdivrp\tst1\n\tfstp\tqword [rsp]\n",
"DCMP": "; DCMP\n\tfld\tqword [rsp+8]\n\tfld\tqword [rsp]\n\tadd\trsp, byte 12\n\tfsubp\tst1\n\tfxtract\n\tffree\tst1\n\tfistp\tqword [rsp]\n",
"DNEG": "; DNEG\n\tfld\tqword [rsp]\n\tfchs\n\tfstp\tqword [rsp]\n",
"LOAD2": "; LOAD2\n\tpop\trax\n\tpush\tqword [rax+4]\n\tpush\tqword [rax]\n",
"STORE2": "; STORE2\n\tpop\trcx\n\tpop\trax\n\tmov\t[rcx], rax\n\tpop\trax\n\tmov\t[rcx+4], rax\n",
"COPY2": "; COPY2\n\tpush\tqword [rsp+4]\n\tpush\tqword [rsp+4]\n",
"DPUSH": "; DPUSH\n\tsub\trsp, byte 8\n\tfstp\tqword [rsp]\n",
"DPOP": "; DPOP\n\tfld\tqword [rsp]\n\tadd\trsp, byte 8\n",
"NIL": "; NIL\n",
"BEGIN": "; BEGIN %s\n",
"END": "; END\n",
"TEXT": "; TEXT\nsegment\t.text\n",
"RODATA": "; RODATA\nsegment\t.rodata\n",
"DATA": "; DATA\nsegment\t.data\n",
"BSS": "; BSS\nsegment\t.bss\n",
"ALIGN": "; ALIGN\nalign\t8\n",
"EXTRN": "; EXTRN\nextern\t$%s\n",
"COMMON": "; COMMON\ncommon\t%d\n",
"GLOBL": "; GLOBL\nglobal\t$%s%s\n",
"LABEL": "; LABEL\n$%s:\n",
"INTEGER": "; INTEGER\n\tdd\t%d\n",
"SHORT": "; SHORT\n\tdw\t%d\n",
"LONG": "; LONG\n\tdq\t%ld\n",
"STR": "; STR\n\tdb\t'%s', 0\n",
"CHAR": "; CHAR\n\tdb\t0x%2.2X\n",
"ID": "; ID\n\tdq\t$%s\n",
"BYTE": "; BYTE\n\tresb\t%d\n",
"FLOAT": "; FLOAT\n\tdd\t%e\n",
"DOUBLE": "; DOUBLE\n\tdq\t%e\n",
"ULDCHR": "; ULDCHR\n\tmovzx\trax,byte [rcx]\n",
"ULD16": "; ULD16\n\tmovzx\trax,word [rcx]\n",
"UDIV": "; UDIV\n\tpop\trcx\n\tpop\trax\n\txor\trdx, rdx\n\tidiv\trcx\n\tpush\trax\n",
"UMOD": "; UMOD\n\tpop\trcx\n\tpop\trax\n\txor\trdx, rdx\n\tidiv\trcx\n\tpush\trdx\n",
"UGT": "; UGT\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tseta\tcl\n\tmov\t[rsp], rcx\n",
"UGE": "; UGE\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetae\tcl\n\tmov\t[rsp], rcx\n",
"ULT": "; ULT\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetb\tcl\n\tmov\t[rsp], rcx\n",
"ULE": "; ULE\n\tpop\trax\n\txor\trcx, rcx\n\tcmp\t[rsp], rax\n\tsetbe\tcl\n\tmov\t[rsp], rcx\n",
"JEQ": "; JEQ\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tje\tnear $%s\n",
"JNE": "; JNE\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjne\tnear $%s\n",
"JGT": "; JGT\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjg\tnear $%s\n",
"JGE": "; JGE\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjge\tnear $%s\n",
"JLT": "; JLT\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjl\tnear $%s\n",
"JLE": "; JLE\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjle\tnear $%s\n",
"JUGT": "; JUGT\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tja\tnear $%s\n",
"JUGE": "; JUGE\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjae\tnear $%s\n",
"JULT": "; JULT\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjbe\tnear $%s\n",
"JULE": "; JULE\n\tpop\trax\n\tpop\trcx\n\tcmp\trcx, rax\n\tjb\tnear $%s\n",

"LD32": "; LD32\n\tpop\trcx\n\tmovsx\trax,dword [rcx]\n\tpush\trax\n", # sign extend
"ST32": "; ST32\n\tpop\trcx\n\tpop\trax\n\tmov\t[rcx], eax\n", # truncate: does not save sign if number overflows 31-bits
"ULD32": "; ULD32\n\tmovzx\trax, dword [rcx]\n", # zero extend

"ASM": "; ASM\n\t%s\n",
"BB": "; BB\n",

"ARG1":	"; ARG1\n\tmov\trdi, [rsp+0]\n",
"ARG2":	"; ARG2\n\tmov\trsi, [rsp+8]\n",
"ARG3":	"; ARG3\n\tmov\trdx, [rsp+16]\n",
"ARG4":	"; ARG4\n\tmov\tr10, [rsp+24]\n",
"ARG5":	"; ARG5\n\tmov\tr8, [rsp+32]\n",
"ARG6":	"; ARG6\n\tmov\tr9, [rsp+40]\n",
"ARG1D":	"; ARG1D\n\tmov\txmm0, [rsp+0]\n",
"ARG2D":	"; ARG2D\n\tmov\txmm1, [rsp+8]\n",
"ARG3D":	"; ARG3D\n\tmov\txmm2, [rsp+16]\n",
"ARG4D":	"; ARG4D\n\tmov\txmm3, [rsp+24]\n",
"ARG5D":	"; ARG5D\n\tmov\txmm4, [rsp+32]\n",
"ARG6D":	"; ARG6D\n\tmov\txmm5, [rsp+40]\n",
"WORD": 8,
"NONE":	"",
"FUNC":	":function",	# global label is a function
"OBJ":	":object",	# global label is data
}
amd64['LD64'] = amd64['LOAD']
amd64['ST64'] = amd64['STORE']
amd64['ULD64'] = amd64['LOAD']
amd64['CONST'] = amd64['LONG']

i386gas = {
"COMM": "# COMM %s\n",
"NOP": "# NOP\n\tnop\n",
"IMM": "# IMM\n\tpushl\t$%d\n",
"ADD": "# ADD\n\tpopl\t%%eax\n\taddl\t%%eax, (%%esp)\n",
"SUB": "# SUB\n\tpopl\t%%eax\n\tsubl\t%%eax, (%%esp)\n",
"MUL": "# MUL\n\tpopl\t%%eax\n\timull\t(%%esp), %%eax\n\tmovl\t%%eax, (%%esp)\n",
"DIV": "# DIV\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tcltd\n\tidivl\t%%ecx\n\tpushl\t%%eax\n",
"MOD": "# MOD\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tcltd\n\tidivl\t%%ecx\n\tpushl\t%%edx\n",
"NEG": "# NEG\n\tnegl\t(%%esp)\n",
"INCR": "# INCR\n\tpopl\t%%eax\n\taddl\t$%d, (%%eax)\n",
"DECR": "# DECR\n\tpopl\t%%eax\n\tsubl\t$%d (%%eax)\n",
"GT": "# GT\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsetg\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"GE": "# GE\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsetge\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"LT": "# LT\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsetl\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"LE": "# LE\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsetle\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"EQ": "# EQ\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsete\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"NE": "# NE\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmp\t%%eax, (%%esp)\n\tsetne\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"AND": "# AND\n\tpopl\t%%eax\n\tandl\t%%eax, (%%esp)\n",
"OR": "# OR\n\tpopl\t%%eax\n\torl\t%%eax, (%%esp)\n",
"XOR": "# XOR\n\tpopl\t%%eax\n\txorl\t%%eax, (%%esp)\n",
"NOT": "# NOT\n\tnotl\t(%%esp)\n",
"ROTL": "# ROTL\n\tpopl\t%%ecx\n\troll\t%%cl, (%%esp)\n",
"ROTR": "# ROTR\n\tpopl\t%%ecx\n\trorl\t%%cl, (%%esp)\n",
"SHTL": "# SHTL\n\tpopl\t%%ecx\n\tsall\t%%cl, (%%esp)\n",
"SHTRU": "# SHTRU\n\tpopl\t%%ecx\n\tshrl\t%%cl, (%%esp)\n",
"SHTRS": "# SHTRS\n\tpopl\t%%ecx\n\tsarl\t%%cl, (%%esp)\n",
"LOCAL": "# LOCAL\n\tleal\t(%%ebp+$%d), %%eax\n\tpushl\t%%eax\n",
"ADDR": "# ADDR\n\tpushl\t$%s\n",
"LOCV": "# LOCV\n\tpushl\t$%d(%%ebp)\n",
"ADDRV": "# ADDRV\n\tpushl\t(%s)\n",
"LOCA": "# LOCA\n\tpopl\t%%eax\n\tmovl\t%%eax, $%d(%%ebp)\n",
"ADDRA": "# ADDRA\n\tpopl\t%%eax\n\tmovl\t%%eax, (%s)\n",
"LOAD": "# LOAD\n\tpopl\t%%eax\n\tpushl\t(%%eax)\n",
"STORE": "# STORE\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tmovl\t%%eax, (%%ecx)\n",

"LDCHR": "# LDCHR\n\tpopl\t%%ecx\n\tmovsbl\t(%%ecx), %%eax\n\tpushl\t%%eax\n",
"STCHR": "# STCHR\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tmovb\t%%al, (%%ecx)\n",
"LD16": "# LD16\n\tpopl\t%%ecx\n\tmovsbw\t(%%ecx), %eax\n\tpushl\t%%eax\n",
"ST16": "# ST16\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tmovw\t%%ax, (%%ecx)\n",
"ENTER": "# ENTER\n\tpushl\t%%ebp\n\tmovl\t%%esp, %%ebp\n\tsubl\t$%d, %%esp\n",
"START": "# START\n\tpushl\t%%ebp\n\tmovl\t%%esp, %%ebp\n",
"ALLOC": "# ALLOC\n\tpopl\t%%eax\n\tsubl\t%%eax, %%esp\n",
"LEAVE": "# LEAVE\n\tleave\n",
"TRASH": "# TRASH\n\tadd\t$%d, %%esp\n",
"CALL": "# CALL\n\tcall\t%s\n",
"RET": "# RET\n\tret\n",
"RETN": "# RETN\n\tret\t$%d\n",
"BRANCH": "# BRANCH\n\tpopl\t%%eax\n\tcall\t%%eax\n",
"LEAP": "# LEAP\n\tpopl\t%%eax\n\tjmp\t%%eax\n",
"JMP": "# JMP\n\tjmp\t%s\n",
"JZ": "# JZ\n\tpopl\t%%eax\n\tcmpl\t$0, %%eax\n\tje\t%s\n",
"JNZ": "# JNZ\n\tpopl\t%%eax\n\tcmpl\t$0, %%eax\n\tjne\t%s\n",
"COPY": "# COPY\n\tpushl\t(%%esp)\n",
"SWAP": "# SWAP\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tpushl\t%%eax\n\tpushl\t%%ecx\n",
"SP": "# SP\n\tpushl\t%%esp\n",
"PUSH": "# PUSH\n\tpushl\t%%eax\n",
"POP": "# POP\n\tpopl\t%%eax\n",
"I2D": "# I2D\n\tfildl\t(%%esp)\n\tsubl\t$4, %%esp\n\tfstpl\t(%%esp)\n",
"F2D": "# F2D\n\tflds\t(%%esp)\n\tsubl\t$4, %%esp\n\tfstpl\t(%%esp)\n",
"D2I": "# D2I\n\tfldl\t(%%esp)\n\taddl\t$4, %%esp\n\tfistpl\t(%%esp)\n",
"D2F": "# D2F\n\tfldl\t(%%esp)\n\taddl\t$4, %%esp\n\tfstps\t(%%esp)\n",
"DADD": "# DADD\n\tfldl\t(%%esp)\n\taddl\t$8, %%esp\n\tfldl\t(%%esp)\n\tfaddp\t%%st(1)\n\tfstpl\t(%%esp)\n",
"DSUB": "# DSUB\n\tfldl\t(%%esp)\n\taddl\t$8, %%esp\n\tfldl\t(%%esp)\n\tfsubp\t%%st(1)\n\tfstpl\t(%%esp)\n",
"DMUL": "# DMUL\n\tfldl\t(%%esp)\n\taddl\t$8, %%esp\n\tfldl\t(%%esp)\n\tfmulp\t%%st(1)\n\tfstpl\t(%%esp)\n",
"DDIV": "# DDIV\n\tfldl\t(%%esp)\n\taddl\t$8, %%esp\n\tfldl\t(%%esp)\n\tfdivp\t%%st(1)\n\tfstpl\t(%%esp)\n",
"DCMP": "# DCMP\n\tfldl\t8(%%esp)\n\tfldl\t(%%esp)\n\taddl\t$12, %%esp\n\tfsubp\t%%st(1)\n\tfxtract\n\tffree\t%%st(1)\n\tfistpl\t(%%esp)\n",
"DNEG": "# DNEG\n\tfldl\t(%%esp)\n\tfchs\n\tfstpl\t(%%esp)\n",
"LOAD2": "# LOAD2\n\tpopl\t%%eax\n\tpushl\t4(%%eax)\n\tpushl\t(%%eax)\n",
"STORE2": "# STORE2\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tmovl\t%%eax, (%%ecx)\n\tpopl\t%%eax\n\tmovl\t%%eax, 4(%%ecx)\n",
"COPY2": "# COPY2\n\tpushl\t4(%%esp)\n\tpushl\t4(%%esp)\n",
"DPUSH": "# DPUSH\n\tsubl\t$8, %%esp\n\tfstpl\t(%%esp)\n",
"DPOP": "# DPOP\n\tfldl\t(%%esp)\n\taddl\t$8, %%esp\n",
"NIL": "# NIL\n",
"BEGIN": "# BEGIN %s\n",
"END": "# END\n",
"TEXT": "# TEXT\n.section\t.text\n",
"RODATA": "# RODATA\n.section\t.rodata\n",
"DATA": "# DATA\n.section\t.data\n",
"BSS": "# BSS\n.section\t.bss\n",
"ALIGN": "# ALIGN\n.align\t4\n",
"EXTRN": "# EXTRN\n.extern\t%s\n",
"COMMON": "# COMMON\n.common\t$%d\n",
"GLOBL": "# GLOBL\n.globl\t%s\t# %s\n",
"LABEL": "# LABEL\n%s:\n",
"INTEGER": "# INTEGER\n\t.int\t%d\n",
"SHORT": "# SHORT\n\t.short\t%d\n",
"LONG": "# LONG\n\t.quad\t%ld\n",
"STR": "# STR\n\t.asciz\t\"%s\"\n",
"CHAR": "# CHAR\n\t.byte\t0x%2.2X\n",
"ID": "# ID\n\t.int\t%s\n",
"BYTE": "# BYTE\n\t.space\t%d\n",
"FLOAT": "# FLOAT\n\t.float\t%e\n",
"DOUBLE": "# DOUBLE\n\t.double\t%e\n",
"ULDCHR": "# ULDCHR\n\tmovzxb\t%%eax, (%%ecx)\n",
"ULD16": "# ULD16\n\tmovzxw\t%%eax, (%%ecx)\n",
"UDIV": "# UDIV\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\txor\t%%edx, %%edx\n\tidiv\t%%ecx\n\tpushl\t%%eax\n",
"UMOD": "# UMOD\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\txor\t%%edx, %%edx\n\tidiv\t%%ecx\n\tpushl\t%%edx\n",
"UGT": "# UGT\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmpl\t%%eax, (%%esp)\n\tseta\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"UGE": "# UGE\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmpl\t%%eax, (%%esp)\n\tsetae\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"ULT": "# ULT\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmpl\t%%eax, (%%esp)\n\tsetb\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"ULE": "# ULE\n\tpopl\t%%eax\n\txorl\t%%ecx, %%ecx\n\tcmpl\t%%eax, (%%esp)\n\tsetbe\t%%cl\n\tmovl\t%%ecx, (%%esp)\n",
"JEQ": "# JEQ\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tje %s\n",
"JNE": "# JNE\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjne %s\n",
"JGT": "# JGT\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjg %s\n",
"JGE": "# JGE\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjge %s\n",
"JLT": "# JLT\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjl %s\n",
"JLE": "# JLE\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjle %s\n",
"JUGT": "# JUGT\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tja %s\n",
"JUGE": "# JUGE\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjae %s\n",
"JULT": "# JULT\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjbe %s\n",
"JULE": "# JULE\n\tpopl\t%%eax\n\tpopl\t%%ecx\n\tcmpl\t%%ecx, %%eax\n\tjb %s\n",

"ST64": "# ST64\n\tpopl\t%%ecx\n\tpopl\t%%eax\n\tmov\t(%%ecx), %%eax\n\tand %%eax, 0x80000000\n\tmov %%eax, 0\n\tmov %%edx, -1\n\tcmovnz %%eax, %%edx\n\tmov (%%ecx+4), %%eax\n", # copy 32bit-sign to upper 32bits

"ASM": "; ASM\n\t%s\n",
"BB": "; BB\n",
"WORD": 4,
"NONE":	"",
"FUNC":	":function",	# global label is a function
"OBJ":	":object",	# global label is data

"ARG1": " ",
"ARG2": " ",
"ARG3": " ",
"ARG4": " ",
"ARG5": " ",
"ARG6": " ",
"ARG1D": " ",
"ARG2D": " ",
"ARG3D": " ",
"ARG4D": " ",
"ARG5D": " ",
"ARG6D": " ",
}
i386gas['LD32'] = i386gas['LOAD']
i386gas['ST32'] = i386gas['STORE']
i386gas['ULD32'] = i386gas['LOAD']
i386gas['LD64'] = i386gas['LOAD'] # who cares if useful data is truncated!
i386gas['ULD64'] = i386gas['LOAD'] # who cares if useful data is truncated!
i386gas['CONST'] = i386gas['INTEGER']

i386 = {
"COMM": "; COMM %s\n",
"NOP": "; NOP\n\tnop\n",
"IMM": "; IMM\n\tpush\tdword %d\n",
"ADD": "; ADD\n\tpop\teax\n\tadd\tdword [esp], eax\n",
"SUB": "; SUB\n\tpop\teax\n\tsub\tdword [esp], eax\n",
"MUL": "; MUL\n\tpop\teax\n\timul\tdword eax, [esp]\n\tmov\t[esp], eax\n",
"DIV": "; DIV\n\tpop\tecx\n\tpop\teax\n\tcdq\n\tidiv\tecx\n\tpush\teax\n",
"MOD": "; MOD\n\tpop\tecx\n\tpop\teax\n\tcdq\n\tidiv\tecx\n\tpush\tedx\n",
"NEG": "; NEG\n\tneg\tdword [esp]\n",
"INCR": "; INCR\n\tpop\teax\n\tadd\tdword [eax], %d\n",
"DECR": "; DECR\n\tpop\teax\n\tsub\tdword [eax], %d\n",
"GT": "; GT\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetg\tcl\n\tmov\t[esp], ecx\n",
"GE": "; GE\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetge\tcl\n\tmov\t[esp], ecx\n",
"LT": "; LT\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetl\tcl\n\tmov\t[esp], ecx\n",
"LE": "; LE\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetle\tcl\n\tmov\t[esp], ecx\n",
"EQ": "; EQ\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsete\tcl\n\tmov\t[esp], ecx\n",
"NE": "; NE\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetne\tcl\n\tmov\t[esp], ecx\n",
"AND": "; AND\n\tpop\teax\n\tand\tdword [esp], eax\n",
"OR": "; OR\n\tpop\teax\n\tor\tdword [esp], eax\n",
"XOR": "; XOR\n\tpop\teax\n\txor\tdword [esp], eax\n",
"NOT": "; NOT\n\tnot\tdword [esp]\n",
"ROTL": "; ROTL\n\tpop\tecx\n\trol\tdword [esp], cl\n",
"ROTR": "; ROTR\n\tpop\tecx\n\tror\tdword [esp], cl\n",
"SHTL": "; SHTL\n\tpop\tecx\n\tsal\tdword [esp], cl\n",
"SHTRU": "; SHTRU\n\tpop\tecx\n\tshr\tdword [esp], cl\n",
"SHTRS": "; SHTRS\n\tpop\tecx\n\tsar\tdword [esp], cl\n",
"LOCAL": "; LOCAL\n\tlea\teax, [ebp+%d]\n\tpush\teax\n",
"ADDR": "; ADDR\n\tpush\tdword $%s\n",
"LOCV": "; LOCV\n\tpush\tdword [ebp+%d]\n",
"ADDRV": "; ADDRV\n\tpush\tdword [$%s]\n",
"LOCA": "; LOCA\n\tpop\teax\n\tmov\t[ebp+%d], eax\n",
"ADDRA": "; ADDRA\n\tpop\teax\n\tmov\t[$%s], eax\n",
"LOAD": "; LOAD\n\tpop\teax\n\tpush\tdword [eax]\n",
"STORE": "; STORE\n\tpop\tecx\n\tpop\teax\n\tmov\t[ecx], eax\n",
"LDCHR": "; LDCHR\n\tpop\tecx\n\tmovsx\teax,byte [ecx]\n\tpush\teax\n",
"STCHR": "; STCHR\n\tpop\tecx\n\tpop\teax\n\tmov\t[ecx], al\n",
"LD16": "; LD16\n\tpop\tecx\n\tmovsx\teax,word [ecx]\n\tpush\teax\n",
"ST16": "; ST16\n\tpop\tecx\n\tpop\teax\n\tmov\t[ecx], ax\n",
"ENTER": "; ENTER\n\tpush\tebp\n\tmov\tebp, esp\n\tsub\tesp, %d\n",
"START": "; START\n\tpush\tebp\n\tmov\tebp, esp\n",
"ALLOC": "; ALLOC\n\tpop\teax\n\tsub\tesp, eax\n",
"LEAVE": "; LEAVE\n\tleave\n",
"TRASH": "; TRASH\n\tadd\tesp, %d\n",
"CALL": "; CALL\n\tcall\t$%s\n",
"RET": "; RET\n\tret\n",
"RETN": "; RETN\n\tret\t%d\n",
"BRANCH": "; BRANCH\n\tpop\teax\n\tcall\teax\n",
"LEAP": "; LEAP\n\tpop\teax\n\tjmp\teax\n",
"JMP": "; JMP\n\tjmp\tdword $%s\n",
"JZ": "; JZ\n\tpop\teax\n\tcmp\teax, byte 0\n\tje\tnear $%s\n",
"JNZ": "; JNZ\n\tpop\teax\n\tcmp\teax, byte 0\n\tjne\tnear $%s\n",
"COPY": "; COPY\n\tpush\tdword [esp]\n",
"SWAP": "; SWAP\n\tpop\teax\n\tpop\tecx\n\tpush\teax\n\tmov\teax, ecx\n\tpush\teax\n",
"SP": "; SP\n\tpush\tesp\n",
"PUSH": "; PUSH\n\tpush\teax\n",
"POP": "; POP\n\tpop\teax\n",
"I2D": "; I2D\n\tfild\tdword [esp]\n\tsub\tesp, byte 4\n\tfstp\tqword [esp]\n",
"F2D": "; F2D\n\tfld\tdword [esp]\n\tsub\tesp, byte 4\n\tfstp\tqword [esp]\n",
"D2I": "; D2I\n\tfld\tqword [esp]\n\tadd\tesp, byte 4\n\tfistp\tdword [esp]\n",
"D2F": "; D2F\n\tfld\tqword [esp]\n\tadd\tesp, byte 4\n\tfstp\tdword [esp]\n",
"DADD": "; DADD\n\tfld\tqword [esp]\n\tadd\tesp, byte 8\n\tfld\tqword [esp]\n\tfaddp\tst1\n\tfstp\tqword [esp]\n",
"DSUB": "; DSUB\n\tfld\tqword [esp]\n\tadd\tesp, byte 8\n\tfld\tqword [esp]\n\tfsubrp\tst1\n\tfstp\tqword [esp]\n",
"DMUL": "; DMUL\n\tfld\tqword [esp]\n\tadd\tesp, byte 8\n\tfld\tqword [esp]\n\tfmulp\tst1\n\tfstp\tqword [esp]\n",
"DDIV": "; DDIV\n\tfld\tqword [esp]\n\tadd\tesp, byte 8\n\tfld\tqword [esp]\n\tfdivrp\tst1\n\tfstp\tqword [esp]\n",
"DCMP": "; DCMP\n\tfld\tqword [esp+8]\n\tfld\tqword [esp]\n\tadd\tesp, byte 12\n\tfsubp\tst1\n\tfxtract\n\tffree\tst1\n\tfistp\tdword [esp]\n",
"DNEG": "; DNEG\n\tfld\tqword [esp]\n\tfchs\n\tfstp\tqword [esp]\n",
"LOAD2": "; LOAD2\n\tpop\teax\n\tpush\tdword [eax+4]\n\tpush\tdword [eax]\n",
"STORE2": "; STORE2\n\tpop\tecx\n\tpop\teax\n\tmov\t[ecx], eax\n\tpop\teax\n\tmov\t[ecx+4], eax\n",
"COPY2": "; COPY2\n\tpush\tdword [esp+4]\n\tpush\tdword [esp+4]\n",
"DPUSH": "; DPUSH\n\tsub\tesp, byte 8\n\tfstp\tqword [esp]\n",
"DPOP": "; DPOP\n\tfld\tqword [esp]\n\tadd\tesp, byte 8\n",
"NIL": "; NIL\n",
"BEGIN": "; BEGIN %s\n",
"END": "; END\n",
"TEXT": "; TEXT\nsegment\t.text\n",
"RODATA": "; RODATA\nsegment\t.rodata\n",
"DATA": "; DATA\nsegment\t.data\n",
"BSS": "; BSS\nsegment\t.bss\n",
"ALIGN": "; ALIGN\nalign\t4\n",
"EXTRN": "; EXTRN\nextern\t$%s\n",
"COMMON": "; COMMON\ncommon\t%d\n",
"GLOBL": "; GLOBL\nglobal\t$%s%s\n",
"LABEL": "; LABEL\n$%s:\n",
"INTEGER": "; INTEGER\n\tdd\t%d\n",
"SHORT": "; SHORT\n\tdw\t%d\n",
"LONG": "; LONG\n\tdq\t%ld\n",
"STR": "; STR\n\tdb\t'%s', 0\n",
"CHAR": "; CHAR\n\tdb\t0x%2.2X\n",
"ID": "; ID\n\tdd\t$%s\n",
"BYTE": "; BYTE\n\tresb\t%d\n",
"FLOAT": "; FLOAT\n\tdd\t%e\n",
"DOUBLE": "; DOUBLE\n\tdq\t%e\n",
"ULDCHR": "; ULDCHR\n\tmovzx\teax,byte [ecx]\n",
"ULD16": "; ULD16\n\tmovzx\teax,word [ecx]\n",
"UDIV": "; UDIV\n\tpop\tecx\n\tpop\teax\n\txor\tedx, edx\n\tidiv\tecx\n\tpush\teax\n",
"UMOD": "; UMOD\n\tpop\tecx\n\tpop\teax\n\txor\tedx, edx\n\tidiv\tecx\n\tpush\tedx\n",
"UGT": "; UGT\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tseta\tcl\n\tmov\t[esp], ecx\n",
"UGE": "; UGE\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetae\tcl\n\tmov\t[esp], ecx\n",
"ULT": "; ULT\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetb\tcl\n\tmov\t[esp], ecx\n",
"ULE": "; ULE\n\tpop\teax\n\txor\tecx, ecx\n\tcmp\t[esp], eax\n\tsetbe\tcl\n\tmov\t[esp], ecx\n",
"JEQ": "; JEQ\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tje\tnear $%s\n",
"JNE": "; JNE\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjne\tnear $%s\n",
"JGT": "; JGT\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjg\tnear $%s\n",
"JGE": "; JGE\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjge\tnear $%s\n",
"JLT": "; JLT\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjl\tnear $%s\n",
"JLE": "; JLE\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjle\tnear $%s\n",
"JUGT": "; JUGT\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tja\tnear $%s\n",
"JUGE": "; JUGE\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjae\tnear $%s\n",
"JULT": "; JULT\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjbe\tnear $%s\n",
"JULE": "; JULE\n\tpop\teax\n\tpop\tecx\n\tcmp\tecx, eax\n\tjb\tnear $%s\n",

"ST64": "; ST64\n\tpop\tecx\n\tpop\teax\n\tmov\t[ecx], eax\n\tand\teax, 0x80000000\n\tmov\teax, 0\n\tmov\tedx, -1\n\tcmovnz\teax, edx\n\tmov\t[ecx+4], eax\n", # copy 32bit-sign to upper 32bits

"ASM": "; ASM\n\t%s\n",
"BB": "; BB\n",

"WORD": 4,
"NONE":	"",
"FUNC":	":function",	# global label is a function
"OBJ":	":object",	# global label is data

"ARG1": " ",
"ARG2": " ",
"ARG3": " ",
"ARG4": " ",
"ARG5": " ",
"ARG6": " ",
"ARG1D": " ",
"ARG2D": " ",
"ARG3D": " ",
"ARG4D": " ",
"ARG5D": " ",
"ARG6D": " ",
}
i386['LD32'] = i386['LOAD']
i386['ST32'] = i386['STORE']
i386['ULD32'] = i386['LOAD']
i386['LD64'] = i386['LOAD'] # who cares if useful data is truncated!
i386['ULD64'] = i386['LOAD'] # who cares if useful data is truncated!
i386['CONST'] = i386['INTEGER']

x64 = {
"COMM": "# COMM %s\n",
"NOP": "# NOP\n\tnop\n",
"IMM": "# IMM\n\tmovq\t$%ld, %%rax\n\tpushq\t%%rax\n", # only MOVs accept 64-bit immediates
"ADD": "# ADD\n\tpopq\t%%rax\n\taddq\t%%rax, (%%rsp)\n",
"SUB": "# SUB\n\tpopq\t%%rax\n\tsubq\t%%rax, (%%rsp)\n",
"MUL": "# MUL\n\tpopq\t%%rax\n\timulq\t(%%rsp), %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DIV": "# DIV\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tcqo\n\tidivq\t%%rcx\n\tpushq\t%%rax\n",
"MOD": "# MOD\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tcqo\n\tidivq\t%%rcx\n\tpushq\t%%rdx\n",
"NEG": "# NEG\n\tnegq\t(%%rsp)\n",
"INCR": "# INCR\n\tpopq\t%%rax\n\taddq\t$%d, (%%rax)\n",
"DECR": "# DECR\n\tpopq\t%%rax\n\tsubq\t$%d, (%%rax)\n",
"GT": "# GT\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetg\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"GE": "# GE\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetge\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"LT": "# LT\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetl\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"LE": "# LE\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetle\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"EQ": "# EQ\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsete\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"NE": "# NE\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetne\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"AND": "# AND\n\tpopq\t%%rax\n\tandq\t%%rax, (%%rsp)\n",
"OR": "# OR\n\tpopq\t%%rax\n\torq\t%%rax, (%%rsp)\n",
"XOR": "# XOR\n\tpopq\t%%rax\n\txorq\t%%rax, (%%rsp)\n",
"NOT": "# NOT\n\tnotq\t(%%rsp)\n",
"ROTL": "# ROTL\n\tpopq\t%%rcx\n\trolq\t%%cl, (%%rsp)\n",
"ROTR": "# ROTR\n\tpopq\t%%rcx\n\trorq\t%%cl, (%%rsp)\n",
"SHTL": "# SHTL\n\tpopq\t%%rcx\n\tsalq\t%%cl, (%%rsp)\n",
"SHTRU": "# SHTRU\n\tpopq\t%%rcx\n\tshrq\t%%cl, (%%rsp)\n",
"SHTRS": "# SHTRS\n\tpopq\t%%rcx\n\tsarq\t%%cl, (%%rsp)\n",
"LOCAL": "# LOCAL\n\tleaq\t%d(%%rbp), %%rax\n\tpushq\t%%rax\n",
"LOCV": "# LOCV\n\tpushq\t%d(%%rbp)\n",
"LOCA": "# LOCA\n\tpopq\t%%rax\n\tmovq\t%%rax, %d(%%rbp)\n",
"LOAD": "# LOAD\n\tpopq\t%%rax\n\tpushq\t(%%rax)\n",
"STORE": "# STORE\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tmovq\t%%rax, (%%rcx)\n",

"ADDR": "# ADDR\n\tleaq\t%s(%%rip), %%rax\n\tpushq\t%%rax\n",
"ADDRV": "# ADDRV\n\tleaq\t%s(%%rip), %%rax\n\tpushq\t(%%rax)\n",
"ADDRA": "# ADDRA\n\tpopq\t%%rcx\n\tleaq\t%s(%%rip), %%rax\n\tmovq\t%%rcx, (%%rax)\n",

"LDCHR": "# LDCHR\n\tpopq\t%%rcx\n\tmovsbq\t(%%rcx), %%rax\n\tpushq\t%%rax\n",
"STCHR": "# STCHR\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tmovb\t%%al, (%%rcx)\n",
"LD16": "# LD16\n\tpopq\t%%rcx\n\tmovswq\t(%%rcx), %%rax\n\tpushq\t%%rax\n",
"ST16": "# ST16\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tmovw\t%%ax, (%%rcx)\n",
"ENTER": "# ENTER\n\tpushq\t%%rbp\n\tmovq\t%%rsp, %%rbp\n\tsubq\t$%d, %%rsp\n",
"START": "# START\n\tpushq\t%%rbp\n\tmovq\t%%rsp, %%rbp\n",
"ALLOC": "# ALLOC\n\tpopq\t%%rax\n\tsubq\t%%rax, %%rsp\n",
"LEAVE": "# LEAVE\n\tleave\n",
"TRASH": "# TRASH\n\tadd\t$%d, %%rsp\n",
"CALL": "# CALL\n\tcall\t%s\n",
"RET": "# RET\n\tret\n",
"RETN": "# RETN\n\tret\t$%d\n",
"BRANCH": "# BRANCH\n\tpopq\t%%rax\n\tcall\t*%%rax\n",
"LEAP": "# LEAP\n\tpopq\t%%rax\n\tjmp\t*%%rax\n",
"JMP": "# JMP\n\tjmp\t%s\n",
"JZ": "# JZ\n\tpopq\t%%rax\n\tcmpq\t$0, %%rax\n\tje\t%s\n",
"JNZ": "# JNZ\n\tpopq\t%%rax\n\tcmpq\t$0, %%rax\n\tjne\t%s\n",
"COPY": "# COPY\n\tpushq\t(%%rsp)\n",
"SWAP": "# SWAP\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tpushq\t%%rax\n\tpushq\t%%rcx\n",
"SP": "# SP\n\tpushq\t%%rsp\n",
"PUSH": "# PUSH\n\tpushq\t%%rax\n",
"POP": "# POP\n\tpopq\t%%rax\n",
"I2D": "# I2D\n\tcvtsi2sdq\t(%%rsp), %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"F2D": "# F2D\n\tpopq\t%%rax\n\tmovq%%rax, %%xmm0\n\tcvtss2sd\t%%xmm0, %%xmm0\n\tmovq\t%%xmm0, %%rax\n\tpushq\t%%rax\n",
"D2I": "# D2I\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tcvttsd2siq\t%%xmm0, %%rax\n\tpushq\t%%rax\n",
"D2F": "# D2F\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tcvtsd2ss\t%%xmm0, %%xmm0\n\tmovq\t%%xmm0, %%rax\n\tpushq\t%%rax\n",
"DADD": "# DADD\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\taddsd\t(%%rsp), %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"DSUB": "# DSUB\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm1\n\tmovq\t(%%rsp), %%xmm0\n\tsubsd\t%%xmm1, %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"DMUL": "# DMUL\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tmulsd\t(%%rsp), %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"DDIV": "# DDIV\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm1\n\tmovq\t(%%rsp), %%xmm0\n\tdivsd\t%%xmm1, %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"DNEG": "# DNEG\n\tmovq\t(%%rsp), %%xmm0\n\tmovq\t$0x8000000000000000, %%rax\n\tmovq\t%%rax, %%xmm1\n\txorpd\t%%xmm1, %%xmm0\n\tmovq\t%%xmm0, (%%rsp)\n",
"DCMP": "# DCMP\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\txorq\t%%rax, %%rax\n\tmov\t$1, %%ecx\n\tmov\t$-1, %%edx\n\tmovsx\t%%edx, %%rdx\n\tucomisd\t(%%rsp), %%xmm0\n\tcmova\t%%rdx, %%rax\n\tcmovb\t%%rcx, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DEQ": "# DEQ\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tsete\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DNE": "# DNE\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tsetne\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DGT": "# DGT\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tsetb\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DGE": "# DGE\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tsetbe\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DLT": "# DLT\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tseta\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"DLE": "# DLE\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n\tucomisd\t(%%rsp), %%xmm0\n\tsetae\t%%al\n\tmovzbl\t%%al, %%rax\n\tmovq\t%%rax, (%%rsp)\n",
"LOAD2": "# LOAD2\n\tpopq\t%%rax\n\tpushq\t(%%rax)\n",
"STORE2": "# STORE2\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tmovq\t%%rax, (%%rcx)\n",
"COPY2": "# COPY2\n\tpushq\t(%%rsp)\n",
"DPUSH": "# DPUSH\n\tmovq\t%%xmm0, %%rax\n\tpushq\t%%rax\n",
"DPOP": "# DPOP\n\tpopq\t%%rax\n\tmovq\t%%rax, %%xmm0\n",

"NIL": "# NIL\n",
"BEGIN": "# BEGIN %s\n",
"END": "# END\n",
"TEXT": "# TEXT\n.section\t.text\n",
"RODATA": "# RODATA\n.section\t.rodata\n",
"DATA": "# DATA\n.section\t.data\n",
"BSS": "# BSS\n.section\t.bss\n",
"ALIGN": "# ALIGN\n.align\t8\n",
"EXTRN": "# EXTRN\n.extern\t%s\n",
"COMMON": "# COMMON\n.comm\t%s,%d\n",
"GLOBL": "# GLOBL\n.globl\t%s\t# %s\n",
"LABEL": "# LABEL\n%s:\n",
"INTEGER": "# INTEGER\n\t.int\t%d\n",
"SHORT": "# SHORT\n\t.short\t%d\n",
"LONG": "# LONG\n\t.quad\t%ld\n",
"STR": "# STR\n\t.asciz\t\"%s\"\n",
"CHAR": "# CHAR\n\t.byte\t0x%2.2X\n",
"ID": "# ID\n\t.quad\t%s\n",
"BYTE": "# BYTE\n\t.space\t%d\n",
"FLOAT": "# FLOAT\n\t.float\t%e\n",
"DOUBLE": "# DOUBLE\n\t.double\t%e\n",
"ULDCHR": "# ULDCHR\n\tmovzxb\t(%%rcx), %%rax\n",
"ULD16": "# ULD16\n\tmovzxw\t(%%rcx), %%rax\n",
"UDIV": "# UDIV\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\txor\t%%rdx, %%rdx\n\tdivq\t%%rcx\n\tpushq\t%%rax\n",
"UMOD": "# UMOD\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\txor\t%%rdx, %%rdx\n\tdivq\t%%rcx\n\tpushq\t%%rdx\n",
"UGT": "# UGT\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tseta\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"UGE": "# UGE\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetae\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"ULT": "# ULT\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetb\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"ULE": "# ULE\n\tpopq\t%%rax\n\txorq\t%%rcx, %%rcx\n\tcmpq\t%%rax, (%%rsp)\n\tsetbe\t%%cl\n\tmovq\t%%rcx, (%%rsp)\n",
"JEQ": "# JEQ\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tje %s\n",
"JNE": "# JNE\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjne %s\n",
"JGT": "# JGT\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjg %s\n",
"JGE": "# JGE\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjge %s\n",
"JLT": "# JLT\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjl %s\n",
"JLE": "# JLE\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjle %s\n",
"JUGT": "# JUGT\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tja %s\n",
"JUGE": "# JUGE\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjae %s\n",
"JULT": "# JULT\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjbe %s\n",
"JULE": "# JULE\n\tpopq\t%%rax\n\tpopq\t%%rcx\n\tcmpq\t%%rax, %%rcx\n\tjb %s\n",

"LD32": "# LD32\n\tpopq\t%%rcx\n\tmovsx\t(%%rcx), %%rax\n\tpushq\t%%rax\n", # sign extend
"ST32": "# ST32\n\tpopq\t%%rcx\n\tpopq\t%%rax\n\tmov\t%%eax, (%%rcx)\n", # truncate: does not save sign if number overflows 31-bits
"ULD32": "# ULD32\n\tmovzx\t(%%rcx), %%rax\n", # zero extend

"ASM": "# ASM\n\t%s\n",
"BB": "# BB\n",

"WORD": 8,
"NONE":	"",
"FUNC":	":function",
"OBJ":	":object",

"ARG1": "# ARG1\n\tmovq\t(%%rbp), %%rdi\n",
"ARG2": "# ARG2\n\tmovq\t8(%%rbp), %%rsi\n",
"ARG3": "# ARG3\n\tmovq\t16(%%rbp), %%rdx\n",
"ARG4": "# ARG4\n\tmovq\t24(%%rbp), %%r10\n",
"ARG5": "# ARG5\n\tmovq\t32(%%rbp), %%r8\n",
"ARG6": "# ARG6\n\tmovq\t40(%%rbp), %%r9\n",
"ARG1D": "# ARG1D\n\tmovq\t(%%rbp), %%xmm0\n",
"ARG2D": "# ARG2D\n\tmovq\t8(%%rbp), %%xmm1\n",
"ARG3D": "# ARG3D\n\tmovq\t16(%%rbp), %%xmm2\n",
"ARG4D": "# ARG4D\n\tmovq\t24(%%rbp), %%xmm3\n",
"ARG5D": "# ARG5D\n\tmovq\t32(%%rbp), %%xmm4\n",
"ARG6D": "# ARG6D\n\tmovq\t40(%%rbp), %%xmm5\n",
}
x64['LD64'] = x64['LOAD']
x64['ST64'] = x64['STORE']
x64['ULD64'] = x64['LOAD']
x64['CONST'] = x64['LONG']
x64['DPUSH'] = x64['PUSH'] # "# DPUSH\n\tsubq\t$8, %%rsp\n\tfstpl\t(%%rsp)\n"
x64['DPOP'] = x64['POP'] # "# DPOP\n\tfldl\t(%%rsp)\n\taddq\t$8, %%rsp\n"

pf = {	'debug': debug, 'num': num, 'arm': arm, 'amd64': amd64,
	'i386gas': i386gas, 'i386': i386, 'x64': x64 }
