// File: /workspace/github_cpp_makefile_star2_O2/temelmertcan[P]multgen/src/multgen.cpp
// Function: main
int main(int argc, char **argv) {

  int  in1_size;
  int  in2_size;
  int  in3_size;
  int  dot_size;
  int  out_size;
  int  shift_amount=0;
  bool allowXes = false;
  string file_name_prefix = "";
  string final_stage_adder;
  string pp_encoding;
  string tree;
  string main_type;
  bool signed_mult;
  bool ha_fa_with_gates;
  queue<string> verilog;

  int retval = interact_with_user(argc, argv, in1_size, in2_size, in3_size, dot_size, out_size, shift_amount, allowXes, signed_mult, ha_fa_with_gates, final_stage_adder,
                                  pp_encoding, tree, main_type,
				  file_name_prefix);

  if (retval==2)
    return 0;

  enter_license(verilog);

  int adder_size;
  string module_name;

  int retval0 = 0, retval1 = 0;

  bool create_fin_adder = true;

  if (main_type.compare("StandAlone") == 0){
    std::list<int> extra_ones_indices;
    bool** zeros_in_output = NULL;

    retval0 = create_mult(in1_size, in2_size,
                          out_size, shift_amount, allowXes,
                          final_stage_adder,
                          pp_encoding,
                          tree,
                          create_fin_adder,
                          module_name,
                          extra_ones_indices,
                          verilog,
                          adder_size,
                          zeros_in_output);
  } else if (main_type.compare("FourMult") == 0) {

    create_four_mult (in1_size, in3_size,
                      out_size, shift_amount, allowXes,
                      final_stage_adder,
                      pp_encoding,
                      tree,
                      module_name,
                      verilog,
                      adder_size);

  } else if (main_type.compare("MAC") == 0){
    create_mac (in1_size,
                in2_size,
                in3_size,
                out_size, shift_amount, allowXes,
                final_stage_adder,
                pp_encoding,
                tree,
                module_name,
                verilog,
                adder_size);
  } else if (main_type.compare("DOT") == 0){
    create_dot (in1_size,
                in2_size,
                in3_size,
                dot_size,
                out_size, shift_amount, allowXes,
                final_stage_adder,
                pp_encoding,
                tree,
                module_name,
                verilog,
                adder_size);
  } else if (main_type.compare("Adder") == 0) {
    create_fin_adder = true;
    module_name = final_stage_adder + "_" + to_string (in1_size);
    adder_size = in1_size;
  } else {
    cout << "not implemented yet!" << endl;
    return 1;
  }

  if (create_fin_adder){
    // if only adder is being asked to create, then create it with carryin. 
    retval1 = create_adder(final_stage_adder, main_type.compare("Adder") == 0, adder_size, verilog);
  }
  if (retval0 == 1 || retval0 == 1)
    return 1;

  create_ha_fa (ha_fa_with_gates, verilog);

  string file_name = file_name_prefix + module_name + "_multgen.sv";
  write_to_file(file_name, verilog);

  cout << endl;
  cout << "Written to " << file_name << endl;
  cout << endl;

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x368, %rsp            # imm = 0x368
andl $0x0, -0x40(%rbp)
movq %rsi, %rbx
movl %edi, %r14d
xorl %r12d, %r12d
movb %r12b, -0x29(%rbp)
leaq 0x22306(%rip), %rsi     # 0x335d1
leaq -0x160(%rbp), %rdi
leaq -0x1b0(%rbp), %rdx
callq 0x20b0
leaq -0xd0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %r12b, (%rax)
leaq -0x130(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
leaq -0x110(%rbp), %rcx
movq %rcx, -0x10(%rcx)
andq $0x0, -0x8(%rcx)
movb %r12b, (%rax)
movb %r12b, (%rcx)
leaq -0xb0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %r12b, (%rax)
leaq -0x1b0(%rbp), %rdi
callq 0x11e0c
leaq -0xc0(%rbp), %rax
leaq -0x120(%rbp), %r10
leaq -0x140(%rbp), %r11
leaq -0xe0(%rbp), %r12
leaq -0x31(%rbp), %r13
leaq -0x51(%rbp), %r15
leaq -0x38(%rbp), %rdx
leaq -0x50(%rbp), %rcx
leaq -0x4c(%rbp), %r8
leaq -0x5c(%rbp), %r9
movl %r14d, %edi
movq %rbx, %rsi
leaq -0x160(%rbp), %rbx
pushq %rbx
pushq %rax
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r15
leaq -0x29(%rbp), %rax
pushq %rax
leaq -0x40(%rbp), %rax
pushq %rax
leaq -0x44(%rbp), %rax
pushq %rax
callq 0x2d1c
addq $0x50, %rsp
xorl %ebx, %ebx
cmpl $0x2, %eax
je 0x118db
leaq -0x1b0(%rbp), %rdi
callq 0x257c
leaq -0xf0(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x1ff47(%rip), %rsi     # 0x31313
leaq -0xc0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x1146c
leaq 0x2002a(%rip), %rsi     # 0x31411
leaq -0xc0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x1155e
leaq 0x2000b(%rip), %rsi     # 0x3140d
leaq -0xc0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x11617
leaq 0x1fffd(%rip), %rsi     # 0x3141a
leaq -0xc0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x116d7
leaq 0x1ffe6(%rip), %rsi     # 0x3141e
leaq -0xc0(%rbp), %rdi
callq 0x2090
testl %eax, %eax
je 0x11937
movq 0x2db75(%rip), %rdi     # 0x3efc8
leaq 0x21227(%rip), %rsi     # 0x32681
callq 0x21c0
movq %rax, %rdi
callq 0x2110
jmp 0x118cc
leaq -0xa0(%rbp), %rbx
movq %rbx, 0x8(%rbx)
movq %rbx, (%rbx)
andq $0x0, 0x10(%rbx)
andq $0x0, -0x80(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x50(%rbp), %r15d
movl -0x44(%rbp), %r12d
movl -0x40(%rbp), %r13d
movb -0x29(%rbp), %r14b
leaq -0x330(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2250
leaq -0x310(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x2250
leaq -0x2f0(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x2250
leaq -0x80(%rbp), %rax
leaq -0x3c(%rbp), %r10
leaq -0x100(%rbp), %r11
movzbl %r14b, %r8d
leaq -0x330(%rbp), %r9
movl -0x30(%rbp), %edi
movl %r15d, %esi
movl %r12d, %edx
movl %r13d, %ecx
pushq %rax
pushq %r10
leaq -0x1b0(%rbp), %rax
pushq %rax
pushq %rbx
pushq %r11
pushq $0x1
leaq -0x2f0(%rbp), %rax
pushq %rax
leaq -0x310(%rbp), %rax
pushq %rax
callq 0x516a
addq $0x40, %rsp
movl %eax, %ebx
leaq -0x2f0(%rbp), %rdi
callq 0x20f0
leaq -0x310(%rbp), %rdi
callq 0x20f0
leaq -0x330(%rbp), %rdi
callq 0x20f0
leaq -0xa0(%rbp), %rdi
callq 0x11f0c
testl %ebx, %ebx
sete %bl
jmp 0x117a9
movl -0x38(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x4c(%rbp), %r15d
movl -0x44(%rbp), %r12d
movl -0x40(%rbp), %r13d
movb -0x29(%rbp), %r14b
leaq -0x2d0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2250
leaq -0x2b0(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x2250
leaq -0x390(%rbp), %rbx
leaq -0x120(%rbp), %rsi
movq %rbx, %rdi
callq 0x2250
subq $0x8, %rsp
leaq -0x3c(%rbp), %rax
leaq -0x100(%rbp), %r10
movzbl %r14b, %r8d
leaq -0x2d0(%rbp), %r9
movl -0x30(%rbp), %edi
movl %r15d, %esi
movl %r12d, %edx
movl %r13d, %ecx
pushq %rax
leaq -0x1b0(%rbp), %rax
pushq %rax
pushq %r10
pushq %rbx
leaq -0x2b0(%rbp), %rax
pushq %rax
callq 0x70d1
addq $0x30, %rsp
leaq -0x390(%rbp), %rdi
callq 0x20f0
leaq -0x2b0(%rbp), %rdi
callq 0x20f0
leaq -0x2d0(%rbp), %rdi
jmp 0x117a2
movl -0x38(%rbp), %r15d
movl -0x50(%rbp), %r12d
movl -0x4c(%rbp), %r13d
movl -0x44(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x48(%rbp)
movb -0x29(%rbp), %r14b
leaq -0x290(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2250
leaq -0x270(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x2250
leaq -0x370(%rbp), %rbx
leaq -0x120(%rbp), %rsi
movq %rbx, %rdi
callq 0x2250
leaq -0x3c(%rbp), %rax
leaq -0x100(%rbp), %r10
movzbl %r14b, %r9d
movl %r15d, %edi
movl %r12d, %esi
movl %r13d, %edx
movl -0x30(%rbp), %ecx
movl -0x48(%rbp), %r8d
pushq %rax
leaq -0x1b0(%rbp), %rax
pushq %rax
pushq %r10
pushq %rbx
leaq -0x270(%rbp), %rax
pushq %rax
leaq -0x290(%rbp), %rax
pushq %rax
callq 0xb8b9
addq $0x30, %rsp
leaq -0x370(%rbp), %rdi
callq 0x20f0
leaq -0x270(%rbp), %rdi
callq 0x20f0
leaq -0x290(%rbp), %rdi
jmp 0x117a2
movl -0x38(%rbp), %r15d
movl -0x50(%rbp), %r12d
movl -0x4c(%rbp), %r13d
movl -0x5c(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x58(%rbp)
movb -0x29(%rbp), %r14b
leaq -0x250(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2250
leaq -0x230(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x2250
leaq -0x350(%rbp), %rbx
leaq -0x120(%rbp), %rsi
movq %rbx, %rdi
callq 0x2250
subq $0x8, %rsp
leaq -0x3c(%rbp), %rax
leaq -0x100(%rbp), %r10
movzbl %r14b, %r11d
movl %r15d, %edi
movl %r12d, %esi
movl %r13d, %edx
movl -0x30(%rbp), %ecx
movl -0x48(%rbp), %r8d
movl -0x58(%rbp), %r9d
pushq %rax
leaq -0x1b0(%rbp), %rax
pushq %rax
pushq %r10
pushq %rbx
leaq -0x230(%rbp), %rax
pushq %rax
leaq -0x250(%rbp), %rax
pushq %rax
pushq %r11
callq 0xddb0
addq $0x40, %rsp
leaq -0x350(%rbp), %rdi
callq 0x20f0
leaq -0x230(%rbp), %rdi
callq 0x20f0
leaq -0x250(%rbp), %rdi
callq 0x20f0
movb $0x1, %bl
leaq -0x1f0(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2250
leaq 0x1fc5b(%rip), %rsi     # 0x3141e
leaq -0xc0(%rbp), %rdi
callq 0x2090
xorl %esi, %esi
testl %eax, %eax
sete %sil
movl -0x3c(%rbp), %edx
leaq -0x1f0(%rbp), %rdi
leaq -0x1b0(%rbp), %rcx
callq 0x48ae
leaq -0x1f0(%rbp), %rdi
callq 0x20f0
testb %bl, %bl
je 0x118cc
movzbl -0x31(%rbp), %edi
leaq -0x1b0(%rbp), %rsi
callq 0x127bc
leaq -0x80(%rbp), %rdi
leaq -0x160(%rbp), %rsi
leaq -0x100(%rbp), %rdx
callq 0x11e2c
leaq 0x20e67(%rip), %rdx     # 0x32696
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x11ba1
leaq -0x80(%rbp), %rdi
callq 0x20f0
leaq -0x1d0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2250
leaq -0x1d0(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x1116a
leaq -0x1d0(%rbp), %rdi
callq 0x20f0
movq 0x2d747(%rip), %rdi     # 0x3efc8
callq 0x2110
movq 0x2d73b(%rip), %rdi     # 0x3efc8
leaq 0x20e0e(%rip), %rsi     # 0x326a2
callq 0x21c0
leaq -0xa0(%rbp), %rsi
movq %rax, %rdi
callq 0x2190
movq %rax, %rdi
callq 0x2110
movq 0x2d711(%rip), %rdi     # 0x3efc8
callq 0x2110
leaq -0xa0(%rbp), %rdi
callq 0x20f0
xorl %ebx, %ebx
jmp 0x118cf
pushq $0x1
popq %rbx
leaq -0x100(%rbp), %rdi
callq 0x20f0
leaq -0x1b0(%rbp), %rdi
callq 0x11f3e
leaq -0xc0(%rbp), %rdi
callq 0x20f0
leaq -0x120(%rbp), %rdi
callq 0x20f0
leaq -0x140(%rbp), %rdi
callq 0x20f0
leaq -0xe0(%rbp), %rdi
callq 0x20f0
leaq -0x160(%rbp), %rdi
callq 0x20f0
movl %ebx, %eax
addq $0x368, %rsp            # imm = 0x368
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x21808(%rip), %rdx     # 0x33146
leaq -0x80(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x11c3b
movl -0x38(%rbp), %esi
leaq -0x210(%rbp), %rdi
callq 0x11c73
leaq -0xa0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x210(%rbp), %rdx
callq 0x11bca
leaq -0x100(%rbp), %rdi
leaq -0xa0(%rbp), %rbx
movq %rbx, %rsi
callq 0x2210
movq %rbx, %rdi
callq 0x20f0
leaq -0x210(%rbp), %rdi
callq 0x20f0
leaq -0x80(%rbp), %rdi
callq 0x20f0
movl -0x38(%rbp), %eax
movl %eax, -0x3c(%rbp)
jmp 0x117a7
movq %rax, %rbx
leaq -0x210(%rbp), %rdi
callq 0x20f0
jmp 0x119c6
movq %rax, %rbx
jmp 0x11abb
jmp 0x11ad4
movq %rax, %rbx
leaq -0x350(%rbp), %rdi
callq 0x20f0
jmp 0x119e4
movq %rax, %rbx
leaq -0x230(%rbp), %rdi
callq 0x20f0
jmp 0x119f5
movq %rax, %rbx
leaq -0x250(%rbp), %rdi
jmp 0x11ae3
movq %rax, %rbx
leaq -0x370(%rbp), %rdi
callq 0x20f0
jmp 0x11a15
movq %rax, %rbx
leaq -0x270(%rbp), %rdi
callq 0x20f0
jmp 0x11a26
movq %rax, %rbx
leaq -0x290(%rbp), %rdi
jmp 0x11ae3
movq %rax, %rbx
leaq -0x390(%rbp), %rdi
callq 0x20f0
jmp 0x11a46
movq %rax, %rbx
leaq -0x2b0(%rbp), %rdi
callq 0x20f0
jmp 0x11a57
movq %rax, %rbx
leaq -0x2d0(%rbp), %rdi
jmp 0x11ae3
movq %rax, %rbx
leaq -0x2f0(%rbp), %rdi
callq 0x20f0
jmp 0x11a77
movq %rax, %rbx
leaq -0x310(%rbp), %rdi
callq 0x20f0
jmp 0x11a88
movq %rax, %rbx
leaq -0x330(%rbp), %rdi
callq 0x20f0
jmp 0x11a99
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x11f0c
jmp 0x11ae8
movq %rax, %rbx
leaq -0x1d0(%rbp), %rdi
callq 0x20f0
jmp 0x11adc
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
jmp 0x11ae3
jmp 0x11ad4
movq %rax, %rbx
leaq -0x1f0(%rbp), %rdi
jmp 0x11ae3
movq %rax, %rbx
jmp 0x11b05
movq %rax, %rbx
jmp 0x11ae8
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x20f0
leaq -0x100(%rbp), %rdi
callq 0x20f0
jmp 0x11af9
movq %rax, %rbx
leaq -0x1b0(%rbp), %rdi
callq 0x11f3e
leaq -0xc0(%rbp), %rdi
callq 0x20f0
leaq -0x120(%rbp), %rdi
callq 0x20f0
leaq -0x140(%rbp), %rdi
callq 0x20f0
leaq -0xe0(%rbp), %rdi
callq 0x20f0
leaq -0x160(%rbp), %rdi
callq 0x20f0
movq %rbx, %rdi
callq 0x2330