// File: stacksmith[P]picoasm/main.cpp
// Function: main
int main(int argc, char **argv)
{

  string strSrcFile;
  string strTplFile;
  string strOutputDir;
  string strEntityName;

  string strTemp;
  int iCompareLen;
  const string strVerilogExt = LA_PICOASM_VERILOG_EXT;

  const char optstring[] = "i:t:d:m:";
  bool bOptErr = false;
  bool bVHDL = true;
  int optch;

  char *cpTemp;
  char *cpBase;
  char *cpExt;

  bool bRet; 
  int iRet = 0;

  while ((optch = getopt(argc, argv, optstring)) != -1){
    switch (optch)
      {
      case 'i': // input source file
	strSrcFile = optarg;
	break;

      case 't': // input template file
	strTplFile = optarg;
	break;

      case 'm': // entity or module name
	strEntityName = optarg;
	break;

      case 'd': // output directory
	strOutputDir = optarg;
	break;

      default:
	cout << "ERR: Unknown command line option" << endl; 
	bOptErr = true;
	break;

      } // switch
  } // while

  // check cmd line options
  if (strSrcFile.empty()){
    cout << "ERR: Input source file missing." << endl; 
    usage(basename(argv[0]));
    return (-1);
  }
  
  if (bOptErr){
    usage(basename(argv[0]));
    return (-1);
  }

  // build optional parms if needed
  if (strOutputDir.empty()){
    cpTemp = strdup(strSrcFile.c_str());
    strOutputDir = dirname(cpTemp);
    free(cpTemp);
  }
  
  if (strEntityName.empty()){
    // build entity name from source file name with no path or extension 
    cpTemp = strdup(strSrcFile.c_str());
    cpBase = basename(cpTemp);
    cpExt = strrchr(cpBase, '.');
    if (cpExt != NULL){
      *cpExt = '\0';
    }
    strEntityName = cpBase;
    free(cpTemp);
  }

  if (strTplFile.empty()){
    // build template file from source file dir + default name
    cpTemp = strdup(strSrcFile.c_str());
    cpBase = dirname(cpTemp);
    strTplFile = cpBase;
    strTplFile += "/";
    strTplFile += LA_PICOASM_DEF_TPL;
    free(cpTemp);
  }

  // determine VHDL or verilog by looking for verilog file extension
  // on template file.
  iCompareLen = strVerilogExt.size();
  if ((strTplFile.size()) > iCompareLen){
    strTemp = strTplFile.substr(strTplFile.size() - iCompareLen, iCompareLen); 
    if (strcasecmp(strTemp.c_str(), strVerilogExt.c_str()) == 0){
      bVHDL = false;   // its verilog
    }
  }

  // debug - show parms
//   cout << "DEBUG: In=" << strSrcFile << endl <<
//     "    OutDir=" << strOutputDir << endl <<
//     "    Entity=" << strEntityName << endl <<
//     "    TemplateFile=" << strTplFile << endl <<
//     "    VHDL=" << bVHDL << endl;  

  m_picoBlaze = new CPicoBlaze();
  m_assembler = new CAssembler();

  m_assembler->setCode(m_picoBlaze->code);
  m_assembler->setFilename(strSrcFile);

  if (m_assembler->assemble() == true){
    // m_picoBlaze->code->Print();
    printListing(strSrcFile);
    if (m_assembler->exportVHDL(strTplFile, 
				strOutputDir, 
				strEntityName,
				bVHDL) == true){
      if (bVHDL){
	cout << "Generated VHDL entity file " 
	     << strOutputDir << "/" << strEntityName 
	     << LA_PICOASM_VHDL_EXT << endl;
      } else {
	cout << "Generated verilog module file " 
	     << strOutputDir << "/" << strEntityName 
	     << LA_PICOASM_VERILOG_EXT << endl;
      }
    } else {
      if (bVHDL){
	cout << "ERR: VHDL entity file not generated" << endl;
      } else {
	cout << "ERR: Verilog module file not generated" << endl;
      }
      iRet = -1;
    }
  } else {
    iRet = -1;
  }

  delete m_assembler;
  delete m_picoBlaze;

  return(iRet);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x320, %rsp            # imm = 0x320
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x4859c0
leaq -0x50(%rbp), %rdi
callq 0x4859c0
leaq -0x70(%rbp), %rdi
callq 0x4859c0
leaq -0x90(%rbp), %rdi
callq 0x4859c0
leaq -0xb0(%rbp), %rdi
callq 0x4859c0
leaq -0xd9(%rbp), %rdi
movq %rdi, -0x238(%rbp)
callq 0x4173f0
movq -0x238(%rbp), %rdx
leaq 0x1868d8(%rip), %rsi    # 0x58b1a5
leaq -0xd8(%rbp), %rdi
callq 0x405840
jmp 0x4048db
leaq -0xd9(%rbp), %rdi
callq 0x417410
movq 0x18698d(%rip), %rax    # 0x58b27b
movq %rax, -0xf5(%rbp)
movb 0x186988(%rip), %al     # 0x58b283
movb %al, -0xed(%rbp)
movb $0x0, -0xf6(%rbp)
movb $0x1, -0xf7(%rbp)
movl $0x0, -0x120(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0xf5(%rbp), %rdx
callq 0x54c7a0
movl %eax, -0xfc(%rbp)
cmpl $-0x1, %eax
je 0x404a46
movl -0xfc(%rbp), %eax
addl $-0x64, %eax
movl %eax, %ecx
movq %rcx, -0x240(%rbp)
subl $0x10, %eax
ja 0x404a09
movq -0x240(%rbp), %rax
leaq 0x1866ac(%rip), %rcx    # 0x58b010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0xd9(%rbp), %rdi
callq 0x417410
jmp 0x40538b
movq $0x609760, %rax         # imm = 0x609760
movq (%rax), %rsi
leaq -0x30(%rbp), %rdi
callq 0x486b20
jmp 0x4049a5
jmp 0x404a41
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x40537f
movq $0x609760, %rax         # imm = 0x609760
movq (%rax), %rsi
leaq -0x50(%rbp), %rdi
callq 0x486b20
jmp 0x4049d6
jmp 0x404a41
movq $0x609760, %rax         # imm = 0x609760
movq (%rax), %rsi
leaq -0x90(%rbp), %rdi
callq 0x486b20
jmp 0x4049f0
jmp 0x404a41
movq $0x609760, %rax         # imm = 0x609760
movq (%rax), %rsi
leaq -0x70(%rbp), %rdi
callq 0x486b20
jmp 0x404a07
jmp 0x404a41
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x18686d(%rip), %rsi    # 0x58b284
callq 0x47f700
movq %rax, -0x248(%rbp)
jmp 0x404a25
movq -0x248(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x404a3a
movb $0x1, -0xf6(%rbp)
jmp 0x404919
leaq -0x30(%rbp), %rdi
callq 0x485ff0
testb $0x1, %al
jne 0x404a58
jmp 0x404b4a
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x18683f(%rip), %rsi    # 0x58b2a5
callq 0x47f700
movq %rax, -0x250(%rbp)
jmp 0x404a74
movq -0x250(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x404a89
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x4dc5c0
movq %rax, -0x260(%rbp)
leaq -0x141(%rbp), %rdi
movq %rdi, -0x258(%rbp)
callq 0x4173f0
movq -0x260(%rbp), %rsi
movq -0x258(%rbp), %rdx
leaq -0x140(%rbp), %rdi
callq 0x405840
jmp 0x404acb
leaq -0x140(%rbp), %rdi
callq 0x4047d0
jmp 0x404ad9
leaq -0x140(%rbp), %rdi
callq 0x485ad0
leaq -0x141(%rbp), %rdi
callq 0x417410
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x148(%rbp)
jmp 0x405334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x404b39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x485ad0
leaq -0x141(%rbp), %rdi
callq 0x417410
jmp 0x40537f
testb $0x1, -0xf6(%rbp)
je 0x404c18
movq -0x10(%rbp), %rax
movq (%rax), %rdi
callq 0x4dc5c0
movq %rax, -0x270(%rbp)
leaq -0x169(%rbp), %rdi
movq %rdi, -0x268(%rbp)
callq 0x4173f0
movq -0x270(%rbp), %rsi
movq -0x268(%rbp), %rdx
leaq -0x168(%rbp), %rdi
callq 0x405840
jmp 0x404b99
leaq -0x168(%rbp), %rdi
callq 0x4047d0
jmp 0x404ba7
leaq -0x168(%rbp), %rdi
callq 0x485ad0
leaq -0x169(%rbp), %rdi
callq 0x417410
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x148(%rbp)
jmp 0x405334
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x404c07
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x485ad0
leaq -0x169(%rbp), %rdi
callq 0x417410
jmp 0x40537f
leaq -0x70(%rbp), %rdi
callq 0x485ff0
testb $0x1, %al
jne 0x404c27
jmp 0x404c65
leaq -0x30(%rbp), %rdi
callq 0x487510
movq %rax, %rdi
callq 0x5011e0
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0x54f580
movq %rax, %rsi
leaq -0x70(%rbp), %rdi
callq 0x486b20
jmp 0x404c59
movq -0x108(%rbp), %rdi
callq 0x4feeb0
leaq -0x90(%rbp), %rdi
callq 0x485ff0
testb $0x1, %al
jne 0x404c77
jmp 0x404cef
leaq -0x30(%rbp), %rdi
callq 0x487510
movq %rax, %rdi
callq 0x5011e0
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0x4dc5c0
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rdi
movl $0x2e, %esi
callq 0x401048
movq %rax, -0x118(%rbp)
cmpq $0x0, -0x118(%rbp)
je 0x404cce
movq -0x118(%rbp), %rax
movb $0x0, (%rax)
movq -0x110(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0x486b20
jmp 0x404ce3
movq -0x108(%rbp), %rdi
callq 0x4feeb0
leaq -0x50(%rbp), %rdi
callq 0x485ff0
testb $0x1, %al
jne 0x404cfe
jmp 0x404d6b
leaq -0x30(%rbp), %rdi
callq 0x487510
movq %rax, %rdi
callq 0x5011e0
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
callq 0x54f580
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x486b20
jmp 0x404d3b
leaq 0x18d49a(%rip), %rsi    # 0x5921dc
leaq -0x50(%rbp), %rdi
callq 0x4872d0
jmp 0x404d4d
leaq 0x186449(%rip), %rsi    # 0x58b19d
leaq -0x50(%rbp), %rdi
callq 0x4872d0
jmp 0x404d5f
movq -0x108(%rbp), %rdi
callq 0x4feeb0
leaq -0xd8(%rbp), %rdi
callq 0x485cf0
movl %eax, -0xb4(%rbp)
leaq -0x50(%rbp), %rdi
callq 0x485cf0
movslq -0xb4(%rbp), %rcx
cmpq %rcx, %rax
jbe 0x404e23
leaq -0x50(%rbp), %rdi
movq %rdi, -0x278(%rbp)
callq 0x485cf0
movq -0x278(%rbp), %rsi
movq %rax, %rdx
movslq -0xb4(%rbp), %rcx
subq %rcx, %rdx
leaq -0x190(%rbp), %rdi
callq 0x4883d0
jmp 0x404dc8
leaq -0xb0(%rbp), %rdi
leaq -0x190(%rbp), %rsi
callq 0x485b20
leaq -0x190(%rbp), %rdi
callq 0x485ad0
leaq -0xb0(%rbp), %rdi
callq 0x487510
movq %rax, -0x280(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x487510
movq -0x280(%rbp), %rdi
movq %rax, %rsi
callq 0x4010d0
cmpl $0x0, %eax
jne 0x404e21
movb $0x0, -0xf7(%rbp)
jmp 0x404e23
movl $0x40, %edi
callq 0x416f20
movq %rax, -0x288(%rbp)
jmp 0x404e36
movq -0x288(%rbp), %rdi
callq 0x413b50
jmp 0x404e44
movq -0x288(%rbp), %rax
movq %rax, 0x1fc806(%rip)    # 0x601658
movl $0x88, %edi
callq 0x416f20
movq %rax, -0x290(%rbp)
jmp 0x404e65
movq -0x290(%rbp), %rdi
callq 0x405d00
jmp 0x404e73
movq -0x290(%rbp), %rax
movq %rax, 0x1fc7df(%rip)    # 0x601660
movq 0x1fc7d8(%rip), %rdi    # 0x601660
movq 0x1fc7c9(%rip), %rax    # 0x601658
movq 0x38(%rax), %rsi
callq 0x4058f0
jmp 0x404e9a
movq 0x1fc7bf(%rip), %rax    # 0x601660
movq %rax, -0x298(%rbp)
leaq -0x1b0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4881b0
jmp 0x404eba
movq -0x298(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x405910
jmp 0x404ecf
leaq -0x1b0(%rbp), %rdi
callq 0x485ad0
movq 0x1fc77e(%rip), %rdi    # 0x601660
callq 0x409b70
movb %al, -0x299(%rbp)
jmp 0x404eef
movb -0x299(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x4052b5
leaq -0x1d0(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x4881b0
jmp 0x404f15
leaq -0x1d0(%rbp), %rdi
callq 0x4053d0
jmp 0x404f23
leaq -0x1d0(%rbp), %rdi
callq 0x485ad0
movq 0x1fc72a(%rip), %rax    # 0x601660
movq %rax, -0x2a8(%rbp)
leaq -0x1f0(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x4881b0
jmp 0x404f4f
leaq -0x210(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x4881b0
jmp 0x404f61
leaq -0x230(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x4881b0
jmp 0x404f76
movq -0x2a8(%rbp), %rdi
movzbl -0xf7(%rbp), %r8d
andl $0x1, %r8d
leaq -0x1f0(%rbp), %rsi
leaq -0x210(%rbp), %rdx
leaq -0x230(%rbp), %rcx
callq 0x408e20
movb %al, -0x2a9(%rbp)
jmp 0x404fab
movb -0x2a9(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x2b0(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x485ad0
leaq -0x210(%rbp), %rdi
callq 0x485ad0
leaq -0x1f0(%rbp), %rdi
callq 0x485ad0
movl -0x2b0(%rbp), %eax
cmpl $0x1, %eax
jne 0x40523a
testb $0x1, -0xf7(%rbp)
je 0x405198
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x1862bb(%rip), %rsi    # 0x58b2c5
callq 0x47f700
movq %rax, -0x2b8(%rbp)
jmp 0x405018
movq -0x2b8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x488450
movq %rax, -0x2c0(%rbp)
jmp 0x405031
movq -0x2c0(%rbp), %rdi
leaq 0x18d19d(%rip), %rsi    # 0x5921dc
callq 0x47f700
movq %rax, -0x2c8(%rbp)
jmp 0x40504d
movq -0x2c8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x488450
movq %rax, -0x2d0(%rbp)
jmp 0x405069
movq -0x2d0(%rbp), %rdi
leaq 0x18626a(%rip), %rsi    # 0x58b2e1
callq 0x47f700
movq %rax, -0x2d8(%rbp)
jmp 0x405085
movq -0x2d8(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x40509a
jmp 0x405238
movq -0x288(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
movl $0x40, %esi
callq 0x416080
jmp 0x40537f
movq -0x290(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
movl $0x88, %esi
callq 0x416080
jmp 0x40537f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x485ad0
jmp 0x40537f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x1d0(%rbp), %rdi
callq 0x485ad0
jmp 0x40537f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x405187
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
jmp 0x40517b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xe8(%rbp)
movl %eax, -0xec(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x485ad0
leaq -0x210(%rbp), %rdi
callq 0x485ad0
leaq -0x1f0(%rbp), %rdi
callq 0x485ad0
jmp 0x40537f
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x186140(%rip), %rsi    # 0x58b2e6
callq 0x47f700
movq %rax, -0x2e0(%rbp)
jmp 0x4051b4
movq -0x2e0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x488450
movq %rax, -0x2e8(%rbp)
jmp 0x4051cd
movq -0x2e8(%rbp), %rdi
leaq 0x18d001(%rip), %rsi    # 0x5921dc
callq 0x47f700
movq %rax, -0x2f0(%rbp)
jmp 0x4051e9
movq -0x2f0(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x488450
movq %rax, -0x2f8(%rbp)
jmp 0x405205
movq -0x2f8(%rbp), %rdi
leaq 0x185f92(%rip), %rsi    # 0x58b1a5
callq 0x47f700
movq %rax, -0x300(%rbp)
jmp 0x405221
movq -0x300(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x405236
jmp 0x405238
jmp 0x4052b3
testb $0x1, -0xf7(%rbp)
je 0x405276
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x1860b4(%rip), %rsi    # 0x58b305
callq 0x47f700
movq %rax, -0x308(%rbp)
jmp 0x40525f
movq -0x308(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x405274
jmp 0x4052a9
movq $0x602580, %rdi         # imm = 0x602580
leaq 0x1860a5(%rip), %rsi    # 0x58b329
callq 0x47f700
movq %rax, -0x310(%rbp)
jmp 0x405292
movq -0x310(%rbp), %rdi
movq $0x47efe0, %rsi         # imm = 0x47EFE0
callq 0x47e1f0
jmp 0x4052a7
jmp 0x4052a9
movl $0xffffffff, -0x120(%rbp) # imm = 0xFFFFFFFF
jmp 0x4052bf
movl $0xffffffff, -0x120(%rbp) # imm = 0xFFFFFFFF
movq 0x1fc39a(%rip), %rax    # 0x601660
movq %rax, -0x318(%rbp)
cmpq $0x0, %rax
je 0x4052f0
movq -0x318(%rbp), %rdi
callq 0x405d60
movq -0x318(%rbp), %rdi
movl $0x88, %esi
callq 0x416080
movq 0x1fc361(%rip), %rax    # 0x601658
movq %rax, -0x320(%rbp)
cmpq $0x0, %rax
je 0x405321
movq -0x320(%rbp), %rdi
callq 0x413cd0
movq -0x320(%rbp), %rdi
movl $0x40, %esi
callq 0x416080
movl -0x120(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x148(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x485ad0
leaq -0xb0(%rbp), %rdi
callq 0x485ad0
leaq -0x90(%rbp), %rdi
callq 0x485ad0
leaq -0x70(%rbp), %rdi
callq 0x485ad0
leaq -0x50(%rbp), %rdi
callq 0x485ad0
leaq -0x30(%rbp), %rdi
callq 0x485ad0
movl -0x4(%rbp), %eax
addq $0x320, %rsp            # imm = 0x320
popq %rbp
retq
leaq -0xd8(%rbp), %rdi
callq 0x485ad0
leaq -0xb0(%rbp), %rdi
callq 0x485ad0
leaq -0x90(%rbp), %rdi
callq 0x485ad0
leaq -0x70(%rbp), %rdi
callq 0x485ad0
leaq -0x50(%rbp), %rdi
callq 0x485ad0
leaq -0x30(%rbp), %rdi
callq 0x485ad0
movq -0xe8(%rbp), %rdi
callq 0x4b74e0
nopw (%rax,%rax)