#!/bin/csh -f

set noglob

set oplist = (dat mov add sub jmp jmz jmn djn cmp spl slt)
set amlist = (imm dir ind dec inc)

cat <<END_OF_TOP
#include <stdio.h>
#include "corewar.h"
#include "sim.h"

#define  INRANGE
#define  DRAW(a, b)
#define  INTERACTIVE  FALSE
#define  IMM1  FALSE
#define  IMM2  FALSE

END_OF_TOP

foreach op ($oplist)
  sed -n "/instruction op_$op/,/instruction done/p" <sim.c >/tmp/op_$op
end

foreach ama ($amlist)
  sed -n "/fetch am_$ama/,/fetch done/p" <sim.c >/tmp/am_$ama
end

foreach op ($oplist)
  set opinfo = `grep "instruction op_$op" sim.c`
  foreach ama ($amlist)
    if ("$ama" == "imm") then
      cat <<IMM1_SETUP
#undef   IMM1
#define  IMM1  TRUE
IMM1_SETUP
    endif
    foreach amb ($amlist)
      cat <<END_OF_FPROLOG
static int  ${op}_${ama}_${amb}(thread_t *th,
                        core_el_t *core,
                        aval_t w_radius,
                        aval_t coresize,
                        aval_t xeq_addr,
                        aval_t arg1,
                        aval_t arg2)  {
	aval_t  addr1, val1;
	aval_t  addr2, val2;
#define  USAGE  $opinfo[4]
#define  ADDR   addr1
#define  VAL    val1
#define  ARG    arg1
#define  TMP1   tmp11
#define  TMP2   tmp12
END_OF_FPROLOG
      if (("$ama" == "dec") || ("$ama" == "inc")) echo "	aval_t  tmp11, tmp12;"
      if (("$amb" == "dec") || ("$amb" == "inc")) echo "	aval_t  tmp21, tmp22;"
      cat </tmp/am_$ama
      cat <<END_OF_ARG1
#undef   USAGE
#undef   ADDR
#undef   VAL
#undef   ARG
#undef   TMP1
#undef   TMP2
#define  USAGE  $opinfo[5]
#define  ADDR   addr2
#define  VAL    val2
#define  ARG    arg2
#define  TMP1   tmp21
#define  TMP2   tmp22
END_OF_ARG1
      cat </tmp/am_$amb
      cat <<END_OF_ARG2
#undef  USAGE
#undef  ADDR
#undef  VAL
#undef  ARG
END_OF_ARG2
      if ("$amb" == "imm") then
        cat <<IMM2_SETUP
#undef   IMM2
#define  IMM2  TRUE
IMM2_SETUP
      endif
      cat </tmp/op_$op
      if ("$amb" == "imm") then
        cat <<IMM2_TEARDOWN
#undef   IMM2
#define  IMM2  FALSE
IMM2_TEARDOWN
      endif
      cat <<END_OF_FTRAILER
#undef  TMP1
#undef  TMP2
}
END_OF_FTRAILER
    end
    if ("$ama" == "imm") then
      cat <<IMM1_TEARDOWN
#undef   IMM1
#define  IMM1  FALSE
IMM1_TEARDOWN
    endif
  end
end

foreach op ($oplist)
  rm /tmp/op_$op
end

foreach ama ($amlist)
  rm /tmp/am_$ama
end


cat <<END_OF_JTHEAD


pintfunc  jmptable[] = {
END_OF_JTHEAD

foreach op ($oplist)
  foreach ama ($amlist)
    foreach amb ($amlist)
      echo ${op}_${ama}_${amb},
    end
  end
end
echo 'NULL};'
