#!/usr/bin/perl -W
#
# fasm2gas.pl - Skrypt konwertujacy kod w skladni FASMa na kod w skladni GAS (GNU as)
# fasm2gas.pl - A script which converts FASM code to GAS (GNU as) code.
#
#	Copyright (C) 2006-2007 Bogdan 'bogdro' Drozdowski, http://rudy.mif.pg.gda.pl/~bogdro/inne/
#		(bogdandr AT op.pl, bogdro AT rudy.mif.pg.gda.pl)
#
#	Licencja / Licence:
#	Powszechna Licencja Publiczna GNU v2 / GNU General Public Licence v2
#
#	Ostatnia modyfikacja / Last modified : 2007-02-02
#
#	Sposob uzycia / Syntax:
#		./fasm2gas.pl xxx.[f]asm [yyy.s]
#
# Jesli nazwa pliku wyjsciowego nie zostanie podana, jest brana taka sama jak pliku
#	wejsciowego (tylko rozszerzenie sie zmieni na .s). Jesli za nazwe
#	pliku wejsciowego podano "-", czytane jest standardowe wejscie.
#	Jesli nazwa pliku wyjsciowego to "-" (lub nie ma jej, gdy wejscie to stdin),
#	wynik bedzie na standardowym wyjsciu.
#
# If there's no output filename, then it is assumed to be the same as the
#	input filename (only the extension will be changed to .s). If the
#	input filename is "-", standard input will be read. If the
#	output filename is "-" (or missing, when input is stdin),
#	the result will be written to the standard output.
#
#    Niniejszy program jest wolnym oprogramowaniem; mozesz go
#    rozprowadzac dalej i/lub modyfikowac na warunkach Powszechnej
#    Licencji Publicznej GNU, wydanej przez Fundacje Wolnego
#    Oprogramowania - wedlug wersji 2-giej tej Licencji lub ktorejs
#    z pozniejszych wersji.
#
#    Niniejszy program rozpowszechniany jest z nadzieja, iz bedzie on
#    uzyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyslnej
#    gwarancji PRZYDATNOSCI HANDLOWEJ albo PRZYDATNOSCI DO OKRESLONYCH
#    ZASTOSOWAN. W celu uzyskania blizszych informacji - Powszechna
#    Licencja Publiczna GNU.
#
#    Z pewnoscia wraz z niniejszym programem otrzymales tez egzemplarz
#    Powszechnej Licencji Publicznej GNU (GNU General Public License);
#    jesli nie - napisz do Free Software Foudation:
#		Free Software Foundation
#		51 Franklin Street, Fifth Floor
#		Boston, MA 02110-1301
#		USA
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foudation:
#		Free Software Foundation
#		51 Franklin Street, Fifth Floor
#		Boston, MA 02110-1301
#		USA

use strict;
use warnings;
use Getopt::Long;

my ($wyj, @instr, @regs, $context);
my ($a1, $a2, $a3, $a4);


# instrukcje do zmiany (instructions to be changed)
@instr = (
		"mov" , "and" , "or"  , "not", "xor", "neg", "cmp", "add" ,
		"sub" , "push", "test", "lea", "pop", "inc", "dec", "idiv",
		"imul", "sbb" , "sal" , "shl", "sar", "shr"
		);

my @regs8 = (
		"al", "bl", "cl", "dl", "r8b", "r9b", "r10b", "r11b",
		"r12b", "r13b", "r14b", "r15b", "sil", "dil", "spl", "bpl",
		"ah", "bh", "ch", "dh"
		);

my @regs16 = (
		"ax", "bx", "cx", "dx", "r8w", "r9w", "r10w", "r11w",
		"r12w", "r13w", "r14w", "r15w", "si", "di", "sp", "bp",
		"cs", "ds", "es", "fg", "gs", "ss"
		);

my @regs32 = (
		"eax",	"ebx", "ecx", "edx", "r8d", "r8l", "r9d", "r9l",
		"r10d", "r10l", "r11d", "r11l", "r12d", "r12l", "r13d", "r13l",
		"r14d", "r14l", "r15d", "r15l", "esi", "edi", "esp", "ebp",
		"cr0", "cr2", "cr3", "cr4",
		"dr0", "dr1", "dr2", "dr3", "dr6", "dr7",
		"st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7",
		);

my @regs64 = (
		"rax", "rbx", "rcx", "rdx", "r8", "r9", "r10", "r11",
		"r12", "r13", "r14", "r15", "rsi", "rdi", "rsp", "rbp", "rip"
		);

my @regmm = (
		"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7",
		"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
		"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
		);

@regs = ( @regs8, @regs16, @regs32, @regs64, @regmm );

sub isreg {

	my $elem = shift;
	foreach(@regs) {
		return 1 if /\b$elem\b/i;
	}
	return 0;
}

sub isreg8 {

	my $elem = shift;
	foreach(@regs8) {
		return 1 if /\b$elem\b/i;
	}
	return 0;
}

sub isreg16 {

	my $elem = shift;
	foreach(@regs16) {
		return 1 if /\b$elem\b/i;
	}
	return 0;
}

sub isreg32 {

	my $elem = shift;
	foreach(@regs32) {
		return 1 if /\b$elem\b/i;
	}
	return 0;
}

my @instrukcje = ("aaa", "aad", "aam", "aas", "adc", "add", "addpd", "addps", "addsd", "addss",
"addsubpd", "addsubps", "and", "andnpd", "andnps", "andpd", "andps", "arpl", "bound", "bsf",
"bsr", "bswap", "bt", "btc", "btr", "bts", "call", "cbw", "cwde", "cwd",
"cdq", "cdqe", "cqo", "clc", "cld", "clgi", "cli", "clts", "clflush", "cmc",
"cmova", "cmovae", "cmovb", "cmovbe", "cmovc", "cmove", "cmovg", "cmovge", "cmovl", "cmovle",
"cmovna", "cmovnae", "cmovnb", "cmovnbe", "cmovnc", "cmovne", "cmovng", "cmovnge", "cmovnl", "cmovnle",
"cmovno", "cmovnp", "cmovns", "cmovnz", "cmovo", "cmovp", "cmovpe", "cmovpo", "cmovs", "cmovz",
"cmp", "cmpeqpd", "cmpeqps", "cmpeqsd", "cmpeqss", "cmplepd", "cmpleps", "cmplesd", "cmpless", "cmpltpd",
"cmpltps", "cmpltsd", "cmpltss", "cmpneqpd", "cmpneqps", "cmpneqsd", "cmpneqss", "cmpnlepd", "cmpnleps", "cmpnlesd",
"cmpnless", "cmpnltpd", "cmpnltps", "cmpnltsd", "cmpnltss", "cmpordpd", "cmpordps", "cmpordsd", "cmpordss", "cmppd",
"cmpps", "cmps", "cmpsb", "cmpsd", "cmpsq", "cmpss", "cmpsw", "cmpunordpd", "cmpunordps", "cmpunordsd",
"cmpunordss", "cmpxchg", "cmpxchg486", "cmpxchg8b", "cmpxchg16b", "comisd", "comiss", "cpuid", "cvtdq2pd", "cvtdq2ps",
"cvtpd2dq", "cvtpd2pi", "cvtpd2ps", "cvtpi2pd", "cvtpi2ps", "cvtps2dq", "cvtps2pd", "cvtps2pi", "cvtsd2si", "cvtsd2ss",
"cvtsi2sd", "cvtsi2ss", "cvtss2sd", "cvtss2si", "cvttpd2dq", "cvttpd2pi", "cvttps2dq", "cvttps2pi", "cvttsd2si", "cvttss2si",
"daa", "das", "dec", "div", "divpd", "divps", "divsd", "divss", "emms", "enter",
"f2xm1", "fabs", "fadd", "faddp", "fbld", "fbstp", "fchs", "fclex", "fnclex", "fcmovb",
"fcmovbe", "fcmove", "fcmovnb", "fcmovnbe", "fcmovne", "fcmovnu", "fcmovu", "fcom", "fcomp", "fcompp",
"fcomi", "fcomip", "fcos", "fdecstp", "fdisi", "feni", "fdiv", "fdivr", "fdivp", "fdivrp",
"femms", "ffree", "ffreep", "fiadd", "ficom", "ficomp", "fidiv", "fidivr", "fild", "fimul",
"fincstp", "finit", "fist", "fistp", "fisttp", "fisub", "fisubr", "fld", "fld1", "fldl2e",
"fldl2t", "fldlg2", "fldln2", "fldcw", "fldenv", "fldpi", "fldz", "fmul", "fmulp", "fndisi",
"fneni", "fninit", "fnop", "fnsave", "fnstcw", "fnstenv", "fnstsw", "fnwait", "fpatan", "fptan",
"fprem", "fprem1", "frndint", "frstor", "frstpm", "fsave", "fscale", "fsetpm", "fsin", "fsincos",
"fsqrt", "fst", "fstp", "fstcw", "fstenv", "fstsw", "fsub", "fsubr", "fsubp", "fsubrp",
"ftst", "fucom", "fucomp", "fucompp", "fucomi", "fucomip", "fwait", "fxam", "fxch", "fxrstor",
"fxsave", "fxtract", "fyl2x", "fyl2xp1", "haddpd", "haddps", "hlt", "hsubpd", "hsubps", "ibts",
"icebp", "idiv", "imul", "in", "inc", "ins", "insb", "insd", "insw", "int",
"int1", "int3", "into", "invd", "invlpg", "invlpga", "iret", "iretd", "iretq", "iretw",
"ja", "jae", "jb", "jbe", "jc", "jcxz", "je", "jecxz", "jg", "jge",
"jl", "jle", "jmp", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", "jng",
"jnge", "jnl", "jnle", "jno", "jnp", "jns", "jnz", "jo", "jp", "jpe",
"jpo", "jrcxz", "js", "jz", "lahf", "lar", "lddqu", "ldmxcsr", "lds", "les",
"lea", "leave", "lfence", "lfs", "lgdt", "lgs", "lidt", "lldt", "lmsw", "loadall",
"loadall286", "loadall386", "lock", "lods", "lodsb", "lodsd", "lodsq", "lodsw", "loop", "loopd",
"loope", "looped", "loopeq", "loopew", "loopne", "loopned", "loopneq", "loopnew", "loopnz", "loopnzd",
"loopnzq", "loopnzw", "loopq", "loopw", "loopz", "loopzd", "loopzq", "loopzw", "lsl", "lss",
"ltr", "maskmovdqu", "maskmovq", "maxpd", "maxps", "maxsd", "maxss", "mfence", "minpd", "minps",
"minsd", "minss", "monitor", "mov", "movapd", "movaps", "movd", "movddup", "movdq2q", "movdqa",
"movdqu", "movhlps", "movhpd", "movhps", "movlhps", "movlpd", "movlps", "movmskpd", "movmskps", "movntdq",
"movnti", "movntpd", "movntps", "movntq", "movq", "movq2dq", "movs", "movsb", "movsd", "movshdup",
"movsldup", "movsq", "movss", "movsx", "movsxd", "movsw", "movupd", "movups", "movzx", "mul",
"mulpd", "mulps", "mulsd", "mulss", "mwait", "neg", "nop", "not", "or", "orpd",
"orps", "out", "outs", "outsb", "outsw", "outsd", "pabsb", "pabsd", "pabsw", "packssdw",
"packsswb", "packuswb", "paddb", "paddd", "paddq", "paddsb", "paddsw", "paddusb", "paddusw", "paddw",
"palignr", "pand", "pandn", "pause", "pavgb", "pavgusb", "pavgw", "pcmpeqb", "pcmpeqw", "pcmpeqd",
"pcmpgtb", "pcmpgtw", "pcmpgtd", "pdistib", "pextrw", "pf2id", "pf2iw", "pfacc", "pfadd", "pfcmpeq",
"pfcmpge", "pfcmpgt", "pfmax", "pfmin", "pfmul", "pfnacc", "pfpnacc", "pfrcp", "pfrcpit1", "pfrcpit2",
"pfrsqit1", "pfrsqrt", "pfsub", "pfsubr", "phaddd", "phaddsw", "phaddw", "phsubd", "phsubsw", "phsubw",
"pi2fd", "pi2fw", "pinsrw", "pmachriw", "pmaddwd", "pmaddubsw", "pmagw", "pmaxsw", "pmaxub", "pminsw",
"pminub", "pmovmskb", "pmulhrw", "pmulhrsw", "pmulhuw", "pmulhw", "pmullw", "pmuludq", "pmvgezb", "pmvlzb",
"pmvnzb", "pmvzb", "pop", "popa", "popaw", "popad", "popd", "popf", "popfw", "popfd",
"popfq", "popq", "popw", "por", "prefetch", "prefetchnta", "prefetcht0", "prefetcht1", "prefetcht2", "prefetchw",
"psadbw", "pshufb", "pshufd", "pshufhw", "pshuflw", "pshufw", "psignb", "psignd", "psignw", "pslld",
"pslldq", "psllq", "psllw", "psrad", "psraw", "psrld", "psrldq", "psrlq", "psrlw", "psubb",
"psubd", "psubq", "psubsb", "psubsiw", "psubsw", "psubusb", "psubusw", "psubw", "pswapd", "punpckhbw",
"punpckhdq", "punpckhqdq", "punpckhwd", "punpcklbw", "punpckldq", "punpcklqdq", "punpcklwd", "push", "pusha", "pushad",
"pushaw", "pushd", "pushf", "pushfd", "pushfq", "pushfw", "pushq", "pushw", "pxor", "rcl",
"rcr", "rcpps", "rcpss", "rdmsr", "rdmsrq", "rdpmc", "rdshr", "rdtsc", "rdtscp", "rep",
"repe", "repne", "repnz", "repz", "ret", "retd", "retf", "retfd", "retfq", "retfw",
"retn", "retnd", "retnq", "retnw", "retq", "retw", "rol", "ror", "rsdc", "rsldt",
"rsm", "rsqrtps", "rsqrtss", "rsts", "sahf", "sal", "sar", "salc", "sbb", "scas",
"scasb", "scasd", "scasq", "scasw", "seta", "setae", "setalc", "setb", "setbe", "setc",
"sete", "setg", "setge", "setl", "setle", "setna", "setnae", "setnb", "setnbe", "setnc",
"setne", "setng", "setnge", "setnl", "setnle", "setno", "setnp", "setns", "setnz", "seto",
"setp", "setpe", "setpo", "sets", "setz", "sfence", "sgdt", "shl", "shld", "shr",
"shrd", "shufpd", "shufps", "sidt", "skinit", "sldt", "smi", "smint", "smintold", "smsw",
"sqrtpd", "sqrtps", "sqrtsd", "sqrtss", "stc", "std", "stgi", "sti", "stmxcsr", "stos",
"stosb", "stosd", "stosq", "stosw", "str", "sub", "subpd", "subps", "subsd", "subss",
"svdc", "svldt", "svts", "swapgs", "syscall", "sysenter", "sysexit", "sysexitq", "sysret", "sysretq",
"test", "ucomisd", "ucomiss", "ud0", "ud1", "ud2", "umov", "unpckhpd", "unpckhps", "unpcklpd",
"unpcklps", "verr", "verw", "vmcall", "vmclear", "vmlaunch", "vmload", "vmmcall", "vmptrld", "vmptrst",
"vmread", "vmresume", "vmrun", "vmsave", "vmwrite", "vmxoff", "vmxon", "wait", "wbinvd", "wrmsr",
"wrmsrq", "wrshr", "xadd", "xbts", "xchg", "xlat", "xlatb", "xor", "xorpd", "xorps",
		);

sub is_instr {

	my $elem = shift;
	foreach(@instrukcje) {
		return 1 if /\b$elem\b/i;
	}
	return 0;
}

sub bezplusa {

	my $elem = shift;
	$elem =~ s/^\s*\++//;
	if ( $elem eq "" ) { $elem = "+"; }
	return $elem;
}

my ($help, $lic, $help_msg, $lic_msg);

$help_msg = "$0: Konwerter z FASMa do GNU as / FASM-to-GNU as converter.\nAutor/Author: Bogdan Drozdowski, ".
	"http://rudy.mif.pg.gda.pl/~bogdro/inne/\n".
	"Skladnia/Syntax: $0 [--help] [--license] xxx.[f]asm [yyy.s]\n\n
 Jesli nazwa pliku wyjsciowego nie zostanie podana, jest brana taka sama jak
pliku wejsciowego (tylko rozszerzenie sie zmieni na .s). Jesli za nazwe
pliku wejsciowego podano \"-\", czytane jest standardowe wejscie.
 Jesli nazwa pliku wyjsciowego to \"-\" (lub nie ma jej, gdy wejscie to stdin),
wynik bedzie na standardowym wyjsciu.

 If there's no output filename, then it is assumed to be the same as the
input filename (only the extension will be changed to .s). If the
input filename is \"-\", standard input will be read.
 If the output filename is \"-\" (or missing, when input is stdin),
the result will be written to the standard output.\n";

$lic_msg = "$0: Konwerter z FASMa do GNU as / FASM-to-GNU as converter.\nAutor/Author: Bogdan Drozdowski, ".
	"http://rudy.mif.pg.gda.pl/~bogdro/inne/\n\n".
	"    Niniejszy program jest wolnym oprogramowaniem; mozesz go
    rozprowadzac dalej i/lub modyfikowac na warunkach Powszechnej
    Licencji Publicznej GNU, wydanej przez Fundacje Wolnego
    Oprogramowania - wedlug wersji 2-giej tej Licencji lub ktorejs
    z pozniejszych wersji.

    Niniejszy program rozpowszechniany jest z nadzieja, iz bedzie on
    uzyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyslnej
    gwarancji PRZYDATNOSCI HANDLOWEJ albo PRZYDATNOSCI DO OKRESLONYCH
    ZASTOSOWAN. W celu uzyskania blizszych informacji - Powszechna
    Licencja Publiczna GNU.

    Z pewnoscia wraz z niniejszym programem otrzymales tez egzemplarz
    Powszechnej Licencji Publicznej GNU (GNU General Public License);
    jesli nie - napisz do Free Software Foudation:
		Free Software Foundation
		51 Franklin Street, Fifth Floor
		Boston, MA 02110-1301
		USA

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software Foudation:
		Free Software Foundation
		51 Franklin Street, Fifth Floor
		Boston, MA 02110-1301
		USA\n";

if ( @ARGV == 0 ) {
	print $help_msg;
	exit 1;
}

Getopt::Long::Configure ( "ignore_case", "ignore_case_always" );

if ( ! GetOptions(
	'h|help|?'		=>	\$help,
	'license|licence|L'	=>	\$lic
	)
   ) {

	print $help_msg;
	exit 1;
}

if ( $lic ) {
	print $lic_msg;
	exit 1;
}

if ( @ARGV == 0 || $help ) {
	print $help_msg;
	exit 1;
}

if ( @ARGV > 1 && $ARGV[0] ne "-" && $ARGV[0] eq $ARGV[1] ) {

	print "$0: Plik wejsciowy i wyjsciowy NIE moga byc takie same.\n";
	print "$0: Input file and output file must NOT be the same.\n";
	exit 4;
}

##########################################################
# Otwieranie plikow (opening the files)

if ( !open ( WE, $ARGV[0] ) ) {
#	$! jest trescia bledu. ($! is the error message)
	print "$0: $ARGV[0]: $!\n";
	exit 2;
}

if ( @ARGV > 1 )  {
	$wyj = $ARGV[1];

} else {
	# bierzemy tylko nazwe pliku (take only the filename)
	($wyj = $ARGV[0]) =~ s/.*\/([^\/]+)/$1/;
# 	Zmieniamy rozszerzenie z .[f]asm na .s (change the extension from .[f]asm to .s)
	$wyj =~ s/\.f?asm$/\.s/;
#	Zmieniamy spacje na podkreslenia (change spaces to underlines)
	$wyj =~ s/\s+/_/g;

	if ( $wyj eq $ARGV[0] && $wyj ne "-" ) { $wyj .= ".s"; }
}

if ( !open ( WY, "> $wyj" ) ) {
	print "$0: $wyj: $!\n";
	close WE;
	exit 3;
}

##########################################################
# Przetwarzanie (processing):

CZYTAJ: while ( <WE> ) {

	#	puste linie przepisujemy (empty lines go without change)
	if (/^\s*$/) {
		print WY "\n";
		next;
	}

	# sprawdzamy, czy komentarz jest jedyny na linii (check if a comment is the only thing on this line)
	if ( /^\s*;.*$/ ) { &komen(1); next; }

	# przetwarzanie dyrektyw kompilacji warunkowej (processing of conditional compiling directives)
	&kom_war(0);

	# zmiana liczb heksadecymalnych na postac 0x... (changing hexadecimal numbers to 0x... form):
	s/\b([[:xdigit:]]+)h/0x$1/gi;
	s/\b\$([[:xdigit:]]+)/0x$1/gi;

	if ( /^\s*\}(.*)$/ ) {

		if ( $context eq "macro" ) { $_ = ".endm $1\n"; print WY; }
		if ( $context eq "irp" || $context eq "rep" ) { $_ = ".endr $1\n"; print WY; }
		$context = "";
		next;
	}


	# ==================== Etykiety (labels)

	# jesli sama w wierszu (if the only thing on a line)
	if ( /^\s*([\w\.]+)\s*:\s*$/ ) 	{ s/\s*(\w+)\s*:\s*$/$1:\n/; print WY; next; }

	# jesli za nia cos jest (if there's something following it)
	s/^\s*([\w\.]+)\s*:\s*(.*)$/$1:\n\t$2/;

	# ==================== Dyrektywy (directives)

	if ( /^\s*format/i )		{ next; }

	if ( /^\s*public\b/i )	 	{ s/^\s*public\s*(.*)/\.globl\t$1/i; print WY; next; }

	if ( /^\s*include\b/i ) 	{ s/^\s*include\s*(.*)/\.include\t$1/i; print WY; next; }

	if ( /^\s*\w+\s+equ\b/i ) 	{ s/^\s*(\w+)\s+equ(.*)/\.equ $1, $2/i; print WY; next; }

	if ( /^\s*align\b/i ) 		{ s/^\s*align\s+(\d+)/\.align $1/i; s/shl/<</i; print WY; next; }

	if ( /^\s*extrn\b/i ) 		{ s/^\s*extrn\s*(.*)/\.extern\t$1/i; print WY; next; }

	if ( /^\s*org\b/i )		{ s/^\s*org(.*)(,.*)?$/\.org\t$1/i; print WY; next; }

	if ( /^\s*macro\b/i )	{

		s/^\s*macro\s+(\w+)\s+([\w,\s]+)/macro $1 $2/i;

		my $args = $2;
		# zmiana przecinków na spacje (change commas to spaces)
		$args =~ s/,//g;

		s/^\s*macro\s+(\w+).*/\.macro\t$1 $args\n/i;
		$context = "macro";
		print WY;
		next;
	}

	if ( /^\s*struc\b/i )	{

		while ( <WE> && ! /^\s*}/ ) {};
		$context = "struc";
		next;
	}

	if ( /^\s*virtual\b/i )	{

		while ( <WE> && ! /^\s*end/ ) {};
		$context = "struc";
		next;
	}

	# ==================== Sekcje (sections)

	if ( /^\s*(section|segment)/i )	{

		if ( /^\s*(section|segment)\s+['"].text['"]/i || /^\s*\.(section|segment).*exec/i  ) { print WY ".text\n"; next; }
		if ( /^\s*(section|segment)\s+['"].data['"]/i || /^\s*\.(section|segment).*write/i ) { print WY ".data\n"; next; }
		if ( /^\s*(section|segment)\s+['"].bss['"]/i ) { print WY ".bss"; next; }

		if ( /^\s*(section|segment)\s+['"](.+)['"](.*)/i ) { print WY "\.section $2\n"; next; }

		if ( /^\s*(section|segment) \.*read/i ) { print WY ".data\n"; next; }
	}

	# ==================== Dane (data)

	if ( /^[^;]*\bdb\b/i )		{

		if ( ! /"/ && ! /'/ ) {
			s/\bdb\b(.*)/\.byte $1/i;
		} else {

			s/^[^;]*\bdb\b//i;
			s/""\s*,?\s*//g;
			s/''//g;
			s/^\s*([^"']+)/\n.byte $1/gi;
			s/\"([^"]*)\"/\n\.ascii "$1"\n/gi;
			s/\'([^']*)\'/\n\.ascii "$1"\n/gi;
			s/\n[^\.\s]/\n.byte/gi;

			s/,\s*$/\n/g;
			s/,\s*\./\n\./g;

		}
		print WY;
		next;
	}
	if ( /^[^;]*\bd[wu]\b/i )		{ s/\bd[wu]\b(.*)/\.word $1/i; print WY; next; }
	if ( /^[^;]*\bdd\b/i )		{
		# float?
		if ( /\d+\./ ) {
			s/\bdd\b(.*)/\.float $1/i;
			print WY;
			next;
		} else {
			s/\bdd\b(.*)/\.long $1/i;
			print WY;
			next;
		}
	}
	if ( /^[^;]*\bd[pf]\b/i )	{ s/\bd[pf]\b(.*)/\.quad $1/i; print WY; next; }
	if ( /^[^;]*\bdq\b/i )		{
		# float?
		if ( /\d+\./ ) {
			s/^\bdq\b(.*)/\.double $1/i;
			print WY;
			next;
		} else {
			s/\bdq\b(.*)/\.quad $1/i;
			print WY;
			next;
		}
	}
	if ( /^[^;]*\bdt\b/i )		{ s/\bdt\b(.*)/\.tfloat $1/i; print WY; next; }

	# times:
	if ( /^[^;]*\btimes\b/i )		{

		my $rozmiar = 1;
		if ( /times\s+(\w+)\s+[rd][wu]\b/i ) { $rozmiar = 2; }
		if ( /times\s+(\w+)\s+[rd]d\b/i ) { $rozmiar = 4; }
		if ( /times\s+(\w+)\s+[rd][pf]\b/i ) { $rozmiar = 6; }
		if ( /times\s+(\w+)\s+[rd]q\b/i ) { $rozmiar = 8; }
		if ( /times\s+(\w+)\s+[rd]t\b/i ) { $rozmiar = 10; }
		s/times\s+(\w+)\s+\w+\s+(.*)/\.fill $1, $rozmiar, $2\n/i;
		print WY;
		next;
	}

	# ==================== Instrukcje (instructions)

	# zmiana kolejnosci argumentow (changing operands' order):
	if ( 		 /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)/\t$1\t$4, $3, $2/;
		}
	}
	if ( 		 /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[:\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$3, $2$4\n/;
		}
	}
	if ( 		 /^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+(\[?[:\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$2$3\n/;
		}
	}

	if ( 		 /^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)/\t$1\t$5, $4, $2/;
		}
	}
	if ( 		 /^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)\s*,\s*(\[?[\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$4, $2$5\n/;
		}
	}
	if ( 		 /^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/ ) {
		if ( is_instr($1) ) {
			s/^\s*(\w+)\s+((t?byte|[dqpft]?word)\s*\[?[\.\w\*\+\-\s\(\)]+\]?)([^,]*(;.*)?)$/\t$1\t$2$4\n/;
		}
	}

	# instrukcjie FPU (FPU instructions)
	s/^\s*fi(\w+)\s+word\s*(.*)/\tfi${1}s\t$2/i;
	s/^\s*fi(\w+)\s+dword\s*(.*)/\tfi${1}l\t$2/i;
	s/^\s*fi(\w+)\s+qword\s*(.*)/\tfi${1}q\t$2/i;

	s/^\s*f([^iI]\w+)\s+dword\s*(.*)/\tf${1}s\t$2/i;
	s/^\s*f([^iI]\w+)\s+qword\s*(.*)/\tf${1}l\t$2/i;
	s/^\s*f([^iI]\w+)\s+t(word|byte)\s*(.*)/\tf${1}t\t$3/i;


	# zamiana "xxx" na "$xxx", jesli nie ma "[]" (change "xxx" to "$xxx", if there are no "[]")
	# nie ruszamy "call/jmp xxx" (don't touch "call/jmp xxx")
	if ( !/^\s*(j[a-z]+|call)/i ) {

		if ( /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)\s*/gi ) {


			$a1 = $1;
			$a2 = $2;
			$a3 = $3;
			$a4 = $4;
			$a1 =~ s/\s+$//;
			$a2 =~ s/\s+$//;
			$a3 =~ s/\s+$//;
			$a4 =~ s/\s+$//;
			$a2 =~ s/(t?byte|[dqpft]?word)//;
			$a3 =~ s/(t?byte|[dqpft]?word)//;
			$a4 =~ s/(t?byte|[dqpft]?word)//;
			$a2 =~ s/^\s+//;
			$a3 =~ s/^\s+//;
			$a4 =~ s/^\s+//;

			if ( $a2 !~ /\[/ && !isreg($a2) ) { $a2 = "\$$a2"; }
			if ( $a3 !~ /\[/ && !isreg($a3) ) { $a3 = "\$$a3"; }
			if ( $a4 !~ /\[/ && !isreg($a4) ) { $a4 = "\$$a4"; }

			$_ = "\t$a1\t$a2, $a3, $a4\n";

		} elsif ( /^\s*(\w+)\s+([^,]+)\s*,\s*([^,]+)\s*/gi ) {

			$a1 = $1;
			$a2 = $2;
			$a3 = $3;
			$a1 =~ s/\s+$//;
			$a2 =~ s/\s+$//;
			$a3 =~ s/\s+$//;
			$a2 =~ s/(t?byte|[dqpft]?word)//;
			$a3 =~ s/(t?byte|[dqpft]?word)//;
			$a2 =~ s/^\s+//;
			$a3 =~ s/^\s+//;

			if ( $a2 !~ /\[/ && !isreg($a2) ) { $a2 = "\$$a2"; }
			if ( $a3 !~ /\[/ && !isreg($a3) ) { $a3 = "\$$a3"; }

			$_ = "\t$a1\t$a2, $a3\n";

		} elsif ( /^\s*(\w+)\s+([^,]+)\s*/gi ) {

			$a1 = $1;
			$a2 = $2;
			$a1 =~ s/\s+$//;
			$a2 =~ s/\s+$//;
			$a2 =~ s/(t?byte|[dqpft]?word)//;
			$a2 =~ s/^\s+//;

			if ( $a2 !~ /\[/ && !isreg($a2) ) { $a2 = "\$$a2"; }

			$_ = "\t$a1\t$a2\n";

		}
	}

	# dodajemy sufiks (add the suffix)
	foreach my $i (@instr) {

		if ( /^\s*$i\s+([^,]+)/i ) {

			($a1 = $1) =~ s/\s+$//;
			if ( /[^;]+\bbyte\b/i )     { s/^\s*$i\b/\t${i}b/i; }
			elsif ( /[^;]+\bword\b/i )  { s/^\s*$i\b/\t${i}w/i; }
			elsif ( /[^;]+\bdword\b/i ) { s/^\s*$i\b/\t${i}l/i; }
			elsif ( /^\s*$i\s+([^,]+)\s*,\s*([^,]+)/i ) {

				($a2 = $2) =~ s/\s+$//;
				if ( $a2 !~ /\[.*\]/ ) {

					if ( isreg8 ($a2) )    { s/^\s*$i\b/\t${i}b/i; }
					elsif ( isreg16($a2) ) { s/^\s*$i\b/\t${i}w/i; }
					elsif ( isreg32($a2) ) { s/^\s*$i\b/\t${i}l/i; }
					elsif ( /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {
						$a1 = $1;
						$a2 = $2;
						$a1 =~ s/\s+$//;
						$a2 =~ s/\s+$//;
						if ( isreg8 ($a1) )    { s/^\s*$i\b/\t${i}b/i; }
						elsif ( isreg16($a1) ) { s/^\s*$i\b/\t${i}w/i; }
						elsif ( isreg32($a1) ) { s/^\s*$i\b/\t${i}l/i; }
						else { s/^\s*$i\b/\t${i}l/i; }
					}
				} elsif ( /^\s*$i\s+([^\[\],]+)\s*,\s*([^,]+)/i ) {

					$a1 = $1;
					$a2 = $2;
					$a1 =~ s/\s+$//;
					$a2 =~ s/\s+$//;
					if ( isreg8 ($a1) )    { s/^\s*$i\b/\t${i}b/i; }
					elsif ( isreg16($a1) ) { s/^\s*$i\b/\t${i}w/i; }
					elsif ( isreg32($a1) ) { s/^\s*$i\b/\t${i}l/i; }
					else { s/^\s*$i\b/\t${i}l/i; }
				} else {
					# domyslny: long (default: long)
					s/^\s*$i\b/\t${i}l/i;
				}
			} else {
				# domyslny: long (default: long)
				s/^\s*$i\b/\t${i}l/i;
			}
		}
	}

	my ($z1, $z2, $z3);
	# Dodanie sufiksow do instrukcji MOVSX/MOVZX
	# (add suffixes to MOVSX/MOVZX instructions)
	if ( /^\s*(mov[sz])x\s+([^,]+)\s*,\s*([^,]+)(.*)/i ) {

		my ($inst, $arg1, $arg2, $reszta);
		$inst = $1;
		$z1 = $2;
		$z2 = $3;
		$reszta = $4;
		($arg1 = $z1) =~ s/\s*$//;
		($arg2 = $z2) =~ s/\s*$//;
		if ( (/\bbyte\b/i || isreg8($arg2) ) && isreg32($arg1) ) {
			$_ = "\t${inst}bl\t$arg1, $arg2 $reszta\n";
		} elsif ( (/\bbyte\b/i || isreg8($arg2) ) || isreg16($arg1) ) {
			$_ = "\t${inst}bw\t$arg1, $arg2 $reszta\n";
		} elsif ( /\bword\b/i || isreg16($arg2) || isreg32($arg1)  ) {
			$_ = "\t${inst}wl\t$arg1, $arg2 $reszta\n";
		}
	}

	s/^\s*cbw\b/\tcbtw/i;
	s/^\s*cwde\b/\tcwtl/i;
	s/^\s*cwd\b/\tcwtd/i;
	s/^\s*cdq\b/\tcltd/i;

	# dodawanie znakow gwiazdki (adding asterisk chars)
	s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*(\[[\w\*\+\-\s]+\])/\t$1\t*$3/i;
	s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*((0x)?\d+h?)/\t$1\t*$3/i;
	s/^\s*(jmp|call)\s+([dp]word|word|near|far|short)?\s*([\w\*\+\-\s]+)/\t$1\t$3/i;
	s/^\s*(jmp|call)\s+([^:]+)\s*:\s*([^:]+)/\tl$1\t$2, $3/i;
	s/^\s*retf\s+(.*)$/\tlret\t$1/i;

	# Zmiana odnoszenia sie do pamieci (changing memory references):

	# seg: disp(base, index, scale)
	# [seg:base+index*scale+disp]
	if ( 		 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $4;
		$a3 = $7;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($3) && isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($3,$5,$6)/;
		} elsif ( isreg($3) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($3,$6,$5)/;
		} elsif ( isreg($5) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($8,$5,$6)/;
		} elsif ( isreg($6) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($8,$6,$5)/;
		} elsif ( isreg($3) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5*$6)$9($3,$8)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z2$5*$6)$9($3)/;
		} elsif ( isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z1$3)$9(,$5,$6)/;
		} elsif ( isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8$z1$3)$9(,$6,$5)/;
		} elsif ( isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6)$9($8)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6$z3$8)$9(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $4;
		$a3 = $6;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($3) && isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z3$7*$8)$9($3,$5)/;
		} elsif ( isreg($5) && isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($5,$7,$8)/;
		} elsif ( isreg($5) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$9($5,$8,$7)/;
		} elsif ( isreg($3) && isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$9($3,$7,$8)/;
		} elsif ( isreg($3) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$9($3,$8,$7)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5$z3$7*$8)$9($3)/;
		} elsif ( isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z3$7*$8)$9($5)/;
		} elsif ( isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$9(,$7,$8)/;
		} elsif ( isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$9(,$8,$7)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5$z3$7*$8)$9(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $5;
		$a3 = $7;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($3) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($6,$3,$4)/;
		} elsif ( isreg($4) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$8)$9($6,$4,$3)/;
		} elsif ( isreg($6) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4)$9($6,$8)/;
		} elsif ( isreg($3) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$9($8,$3,$4)/;
		} elsif ( isreg($4) && isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$9($8,$4,$3)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6$z3$8)$9(,$3,$4)/;
		} elsif ( isreg($4) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6$z3$8)$9(,$4,$3)/;
		} elsif ( isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z3$8)$9($6)/;
		} elsif ( isreg($8) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6)$9($8)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6$z3$8)$9(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $4;
		$a3 = $6;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($3) && isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z3$7)$8($3,$5,)/;
		} elsif ( isreg($3) && isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$8($3,$7,)/;
		} elsif ( isreg($5) && isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$8($7,$5,)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$5$z3$7)$8($3)/;
		} elsif ( isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z3$7)$8($5)/;
		} elsif ( isreg($7) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$8($7)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5$z3$7)$8(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $4;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($3) && isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($3,$5,$6)/;
		} elsif ( isreg($3) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($3,$6,$5)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5*$6)$7($3)/;
		} elsif ( isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$7(,$5,$6)/;
		} elsif ( isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$7(,$6,$5)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5*$6)$7(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $4;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($3) && isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($3,$5,)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$5)$6($3)/;
		} elsif ( isreg($5) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3)$6($5)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3$z2$5)$6(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*(\w+)\s*\]/ ) {
		if ( isreg($2) ) {
			s/\[\s*(\w+)\s*:\s*(\w+)\s*\]/$1:($2)/;
		} else {
			s/\[\s*(\w+)\s*:\s*(\w+)\s*\]/$1:$2(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $2;
		$a2 = $5;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($3) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($6,$3,$4)/;
		} elsif ( isreg($4) && isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($6,$4,$3)/;
		} elsif ( isreg($3) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$7(,$3,$4)/;
		} elsif ( isreg($4) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z2$6)$7(,$4,$3)/;
		} elsif ( isreg($6) ) {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4)$7($6)/;
		} else {
			s/\[\s*(\w+)\s*:\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/$1:($z1$3*$4$z2$6)$7(,1)/;
		}
	}

	# disp(base, index, scale)
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $3;
		$a3 = $6;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($2) && isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($2,$4,$5)/;
		} elsif ( isreg($2) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($2,$5,$4)/;
		} elsif ( isreg($2) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4*$5)$8($2,$7)/;
		} elsif ( isreg($4) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($7,$4,$5)/;
		} elsif ( isreg($5) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($7,$5,$4)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7$z2$4*$5)$8($2)/;
		} elsif ( isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7+$z1$2)$8(,$4,$5)/;
		} elsif ( isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7+$z1$2)$8(,$5,$4)/;
		} elsif ( isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5)$8($7)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5$z3$7)$8(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $4;
		$a3 = $6;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($2) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($5,$2,$3)/;
		} elsif ( isreg($3) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$7)$8($5,$3,$2)/;
		} elsif ( isreg($2) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$8($7,$2,$3)/;
		} elsif ( isreg($3) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$8($7,$3,$2)/;
		} elsif ( isreg($5) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3)$8($5,$7)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5z3$7)$8(,$2,$3)/;
		} elsif ( isreg($3) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5z3$7)$8(,$3,$2)/;
		} elsif ( isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z3$7)$8($5)/;
		} elsif ( isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5)$8($7)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5$z3$7)$8(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $3;
		$a3 = $5;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($2) && isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z3$6*$7)$8($2,$4)/;
		} elsif ( isreg($2) && isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4)$8($2,$6,$7)/;
		} elsif ( isreg($2) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4)$8($2,$7,$6)/;
		} elsif ( isreg($4) && isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($4,$6,$7)/;
		} elsif ( isreg($4) && isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$8($4,$7,$6)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4$z3$6*$7)$8($2)/;
		} elsif ( isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z3$6*$7$z1$2)$8($4)/;
		} elsif ( isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$8(,$6,$7)/;
		} elsif ( isreg($7) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$8(,$7,$6)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4$z3$6*$7)$8(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $3;
		$a3 = $5;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		$z3 = bezplusa($a3);
		if ( isreg($2) && isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6)$7($2,$4)/;
		} elsif ( isreg($2) && isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4)$7($2,$6)/;
		} elsif ( isreg($4) && isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$7($4,$6)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6$z2$4)$7($2)/;
		} elsif ( isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z3$6+$z1$2)$7($4)/;
		} elsif ( isreg($6) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4)$7($6)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4$z3$6)$7(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $3;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($2) && isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($2,$4,$5)/;
		} elsif ( isreg($2) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($2,$5,$4)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z2$4*$5)$6($2)/;
		} elsif ( isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$6(,$4,$5)/;
		} elsif ( isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2)$6(,$5,$4)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*\*\s*(\w+)\s*(\)*)\s*\]/($z1$2$z2$4*$5)$6(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $3;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($2) && isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($2,$4)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$4)$5($2)/;
		} elsif ( isreg($4) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2)$5($4)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($2$z2$4)$5(,1)/;
		}
	}
	elsif ( 	 /\[\s*(\w+)\s*\]/ ) {
		if ( isreg($1) ) {
			# disp(base)
			s/\[\s*(\w+)\s*\]/($1)/;
		} else {
			s/\[\s*(\w+)\s*\]/$1(,1)/;
		}
	}
	elsif ( 	 /\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/ ) {
		$a1 = $1;
		$a2 = $4;
		$z1 = bezplusa($a1);
		$z2 = bezplusa($a2);
		if ( isreg($2) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($5,$2,$3)/;
		} elsif ( isreg($3) && isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($5,$3,$2)/;
		} elsif ( isreg($2) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$6(,$2,$3)/;
		} elsif ( isreg($3) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z2$5)$6(,$3,$2)/;
		} elsif ( isreg($5) ) {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3)$6($5)/;
		} else {
			s/\[\s*([\+\-\(\)]*)\s*(\w+)\s*\*\s*(\w+)\s*([\+\-\(\)]+)\s*(\w+)\s*(\)*)\s*\]/($z1$2*$3$z2$5)$6(,1)/;
		}
	}

	# zmiana "stN" na "st(N)" (changing "stN" to "st(N)")
	s/\bst(\d)\b/\%st($1)/g;


	# Dodawanie znakow procenta (adding percent chars)
	foreach my $r (@regs) {

		s/\b$r\b/\%$r/gi;
	}

	# REP**: dodajemy znak konca linii (REP**: adding the end of line char)
	s/^\s*(rep[enz]{0,2})\s+/\t$1\n\t/i;


	# zmiana komentarzy (change the comments)
	&komen(0);

	print WY;

}


##########################################################
# Zmiana komentarzy (changing the comments).
# GAS ma takie same komentarze, jak C (GAS has the same comments as C)

sub	komen {

	# parametr = 0 => nie ma drukowania (when the parameter is 0, there will be no printing)
	my $drukuj = shift;

	s/;(.*)/\/\* $1 \*\//;

	print WY if $drukuj;
}

##########################################################
# Kompilacja warunkowa (conditional compiling)

sub	kom_war {

	# parametr = 0 => nie ma drukowania (when the parameter is 0, there will be no printing)
	my $drukuj = shift;

	# sklejanie argumentow: (concatenating arguments:)
	s/#/,/g;

	s/^[\{\s]+$/\n/g;

	# purge:
	if ( /^\s*(purge|restruc)/i )	{

		if ( $drukuj ) { print WY "\.err \"WARNING: skipped PURGE/RESTRUC\""; }
		return;
	}

	# rept:
	if ( /^\s*rept/i )	{

		if ( /}/ ) {
			s/^\s*rept\s+(\d+)\s*[\w\:]+\s*\{([\w\s]+)\}/.rept $1\n$2\n/i;
		} else {
			s/^\s*rept\s+(\d+)\s*[\w\:]+\s*\{?/.rept $1\n/i;
			$context = "rep";
		}
		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*repeat/i )	{

		s/^\s*repeat\s+(\d+)/.rept $1\n/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	# irp/s:
	if ( /^\s*irps?/i )	{

		if ( /}/ ) {
			s/^\s*irps?\s+(\d+)\s*[\w\:]+\s*\{([\w\s]+)\}/\.irp $1\n$2\n/i;
		} else {
			s/^\s*irps?\s+(\d+)\s*[\w\:]+\s*\{?/\.irp $1\n/i;
			$context = "irp";
		}
		if ( $drukuj ) { print WY; }
		return;
	}

	# match:
	if ( /^\s*match/i )	{

		if ( $drukuj ) { print WY "\.err \"WARNING: skipped MATCH\""; }
		return;
	}

	# end repeat:
	if ( /^\s*end\s+repeat/i )	{

		s/^\s*end\s+repeat\s+(\w+)/\.endr\t$1/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	#	Definicje stalych (definitions of constants)
	if ( /^\s*\w+\s*=\s*\w+/ ) {

		s/^\s*(\w+)\s*=\s*(\w+)(.*)/\t.equ \t$1, $2 $3\n/;
		if ( $drukuj ) { print WY; }
	}

	#	Kompilacja warunkowa (conditional compiling)
	if ( /^\s*if\s+defined/i ) {

		s/^\s*if\s+defined(.*)$/\.ifdef $1/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*if\s+~\s*defined/i ) {

		s/^\s*if\s+~\s*defined(.*)$/\.ifndef $1/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*end\s+if/i ) {

		s/^\s*end\s+if.*$/\.endif/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*else\s+if/i ) {

		s/^\s*else\s+if(.*)$/\.elseif $1/i;

	#	Operatory logiczne, mod i div (logical operators, mod and div):
		s/and/&&/gi;
		s/or/||/gi;
		s/&/&&/g;
		s/\|/||/g;
		s/xor/^^/gi;
		s/~/!/g;
		s/mod/\%/gi;
		s/div/\//gi;
		s/shl/<</gi;
		s/shr/>>/gi;

		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*else/i ) {

		s/^\s*else(.*)$/\.else $1/i;
		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*if/i ) {

		s/^\s*if(.*)$/\.if $1/i;

	#	Operatory logiczne, mod i div (logical operators, mod and div):
		s/and/&&/gi;
		s/or/||/gi;
		s/&/&&/g;
		s/\|/||/g;
		s/xor/^^/gi;
		s/~/!/g;
		s/mod/\%/gi;
		s/div/\//gi;
		s/shl/<</gi;
		s/shr/>>/gi;

		if ( $drukuj ) { print WY; }
		return;
	}

	if ( /^\s*display/i  ) {

		s/^\s*display(.*)$/\.err "$2"/i;
		if ( $drukuj ) { print WY; }
	}

}


##########################################################
# Koniec (the end):

close WY;
close WE;

