// SDB-CGEN V1.8.0
// gcc -DMAIN=1 mips.c ; ./a.out > mips.h
#include <ctype.h>
#include <stdio.h>
#include <string.h>

struct kv { const char *name; const char *value; };
static struct kv kvs[] = {
  {"abs.fmt","floating point absolute value"}, 
  {"add","adds two registers, trap on overflow"}, 
  {"add.fmt","floating point add"}, 
  {"addi","add sign-extended constants (or copy one register to another: addi $1, $2, 0), trap on overflow"}, 
  {"addiu","add sign-extended constants (or copy one register to another: addi $1, $2, 0)"}, 
  {"addu","adds two registers"}, 
  {"alnv.ps","floating point align variable"}, 
  {"and","bitwise and"}, 
  {"andi","bitwise and, leftmost 16 bits are padded with 0s"}, 
  {"b","unconditional branch"}, 
  {"bal","branch and link"}, 
  {"bc1f","branch on fp false"}, 
  {"bc1fl","branch on fp false likely"}, 
  {"bc1t","branch on fp true"}, 
  {"bc1tl","branch on fp true likely"}, 
  {"bc2f","branch on cop2 false"}, 
  {"bc2fl","branch on cop2 false likely"}, 
  {"bc2t","branch on cop2 true"}, 
  {"bc2tl","branch on cop2 true likely"}, 
  {"beq","beq $s,$t,C, goes to the instruction at the specified address if two registers are equal."}, 
  {"beql","branch on equal likely"}, 
  {"bgez","branch on greater than or equal to zero"}, 
  {"bgezal","branch on greater than or equal to zero and link"}, 
  {"bgezall","branch on greater than or equal to zero and link likely"}, 
  {"bgezl","branch on greater than or equal to zero likely"}, 
  {"bgtz","branch on greater than zero"}, 
  {"bgtzl","branch on greater than zero likely"}, 
  {"blez","branch if the register is less than or equal to zero."}, 
  {"blezl","branch on less than or equal to zero likely"}, 
  {"bltz","branch on less than zero"}, 
  {"bltzal","branch on less than zero and link"}, 
  {"bltzall","branch on less than zero and link likely"}, 
  {"bltzl","branch on less than zero likely"}, 
  {"bne","branch on not equal"}, 
  {"bnel","branch on not equal likely"}, 
  {"bneq","goes to the instruction at the specified address if two registers are not equal."}, 
  {"break","breakpoint"}, 
  {"c.cond.fmt","floating point compare"}, 
  {"cache","perform cache operation."}, 
  {"ceil.l.fmt","fixed point ceiling convert to long fixed point"}, 
  {"ceil.w.fmt","floating point ceiling convert to word fixed point"}, 
  {"cfc1","move control word from floating point"}, 
  {"cfc2","move control word from coprocessor 2"}, 
  {"clo","count leading ones in word"}, 
  {"clz","count leading zeros in word"}, 
  {"cop2","coprocessor operation to coprocessor 2"}, 
  {"ctc1","move control word to floating point"}, 
  {"ctc2","move control word to coprocessor 2"}, 
  {"cvt.d.fmt","floating point convert to double floating point"}, 
  {"cvt.l.fmt","floating point convert to long fixed point"}, 
  {"cvt.ps.s","floating point convert pair to paired single"}, 
  {"cvt.s.fmt","floating point convert to single floating point"}, 
  {"cvt.s.pl","floating point convert pair lower to single floating point"}, 
  {"cvt.s.pu","floating point convert pair upper to single floating point"}, 
  {"cvt.w.fmt","floating point convert to word fixed point"}, 
  {"dadd","doubleword add"}, 
  {"daddi","doubleword add immediate"}, 
  {"daddiu","doubleword add immediate unsigned"}, 
  {"daddu","doubleword add unsigned"}, 
  {"dclo","count leading ones in doubleword"}, 
  {"dclz","count leading zeros in doubleword"}, 
  {"ddiv","doubleword divide"}, 
  {"ddivu","doubleword divide unsigned"}, 
  {"deret","debug exception return"}, 
  {"dext","doubleword extract bit field"}, 
  {"dextm","doubleword extract bit field middle"}, 
  {"dextu","doubleword extract bit field upper"}, 
  {"di","disable interrupts"}, 
  {"dins","doubleword insert bit field"}, 
  {"dinsm","doubleword insert bit field middle"}, 
  {"dinsu","doubleword insert bit field upper"}, 
  {"div","divides two registers and puts the 32-bit integer result in LO and the remainder in HI."}, 
  {"div.fmt","floating point divide"}, 
  {"divu","divides two registers and puts the 32-bit integer result in LO and the remainder in HI."}, 
  {"dmfc0","doubleword move from coprocessor 0"}, 
  {"dmfc1","doubleword move from floating point"}, 
  {"dmfc2","doubleword move from coprocessor 2"}, 
  {"dmtc0","doubleword move to coprocessor 0"}, 
  {"dmtc1","doubleword move to floating point"}, 
  {"dmtc2","doubleword move to coprocessor 2"}, 
  {"dmult","doubleword multiply"}, 
  {"dmultu","doubleword multiply unsigned"}, 
  {"drotr","doubleword rotate right"}, 
  {"drotr32","doubleword rotate right plus 32"}, 
  {"drotrv","doubleword rotate right variable"}, 
  {"dsbh","doubleword swap bytes within halfwords"}, 
  {"dshd","doubleword swap halfwords within doublewords"}, 
  {"dsll","doubleword shift left logical"}, 
  {"dsll32","doubleword shift left logical plus 32"}, 
  {"dsllv","doubleword shift left logical variable"}, 
  {"dsra","doubleword shift right arithmetic"}, 
  {"dsra32","doubleword shift right arithmetic plus 32"}, 
  {"dsrav","doubleword shift right arithmetic variable"}, 
  {"dsrl","doubleword shift right logical"}, 
  {"dsrl32","doubleword shift right logical plus 32"}, 
  {"dsrlv","doubleword shift right logical variable"}, 
  {"dsub","doubleword subtract"}, 
  {"dsubu","doubleword subtract unsigned"}, 
  {"ehb","execution hazard barrier"}, 
  {"ei","enable interrupts"}, 
  {"eret","exception return"}, 
  {"ext","extract bit field"}, 
  {"floor.l.fmt","floating point floor convert to long fixed point"}, 
  {"floor.w.fmt","floating point floor convert to word fixed point"}, 
  {"ins","insert bit field"}, 
  {"j","unconditionally jumps to the instruction at the specified address"}, 
  {"jal","used to call a subroutine, $31 holds the return address; returning from a subroutine is done by: jr $31. Return address is PC + 8, not PC + 4 due to the use of a branch delay slot which forces the instruction after the jump to be executed"}, 
  {"jalr","jump and link register"}, 
  {"jalr.hb","jump and link register with hazard barrier"}, 
  {"jr","jumps to the address contained in the specified register"}, 
  {"jr.hb","jump register with hazard barrier"}, 
  {"jraddiusp","increment stackpointer and jump to ra register"}, 
  {"lb","lb $t,C($s), loads the byte stored from: MEM[$s+C], sign is extended to width of register"}, 
  {"lbu","load byte unsigned"}, 
  {"ld","load doubleword"}, 
  {"ldc1","load doubleword to floating point"}, 
  {"ldc2","load doubleword to coprocessor 2"}, 
  {"ldl","load doubleword left"}, 
  {"ldr","load doubleword right"}, 
  {"ldxc1","load doubleword indexed to floating point"}, 
  {"lh","lh $t,C($s), loads the halfword stored from: MEM[$s+C] and the following byte, sign is extended to width of register."}, 
  {"lhu","lhu $t,C($s), loads the halfword stored from: MEM[$s+C] and the following byte."}, 
  {"li","load immediate (pseudoinstruction)"}, 
  {"ll","load linked word"}, 
  {"lld","load linked doubleword"}, 
  {"lui","loads a 16-bit immediate operand into the upper 16-bits of the register specified."}, 
  {"luxc1","load doubleword indexed unaligned to floating point"}, 
  {"lw","lw $t,C($s), loads the word stored from: MEM[$s+C] and the following 3 bytes."}, 
  {"lwc1","load word to floating point"}, 
  {"lwc2","load word to coprocessor 2"}, 
  {"lwl","load word left"}, 
  {"lwr","load word right"}, 
  {"lwu","load word unsigned"}, 
  {"lwxc1","load word indexed to floating point"}, 
  {"madd","multiply and add word to hi,lo"}, 
  {"madd.fmt","floating point multiply add"}, 
  {"maddu","multiply and add unsigned word to hi,lo"}, 
  {"mfc0","move from coprocessor 0"}, 
  {"mfc1","move word from floating point"}, 
  {"mfc2","move word from coprocessor 2"}, 
  {"mfcZ","moves a 4 byte value from Coprocessor Z Control register to a general purpose register. Sign extension."}, 
  {"mfhc1","move word from high half of floating point register"}, 
  {"mfhc2","move word from high half of coprocessor 2 register"}, 
  {"mfhi","moves a value from HI to a register"}, 
  {"mflo","moves a value from LO to a register"}, 
  {"mov.fmt","floating point move"}, 
  {"move","moves a register value into another register (pseudoinstruction)."}, 
  {"movf","move conditional on floating point false"}, 
  {"movf.fmt","floating point move conditional on floating point false"}, 
  {"movn","conditional move."}, 
  {"movn.fmt","floating point move conditional on not zero"}, 
  {"movt","move conditional on floating point true"}, 
  {"movt.fmt","floating point move conditional on floating point true"}, 
  {"movz","conditional move."}, 
  {"movz.fmt","floating point move conditional on zero"}, 
  {"msub","multiply and subtract word to hi,lo"}, 
  {"msub.fmt","floating point multiply subtract"}, 
  {"msubu","multiply and subtract word to hi,lo"}, 
  {"mtc0","move to coprocessor 0"}, 
  {"mtc1","move word to floating point"}, 
  {"mtc2","move word to coprocessor 2"}, 
  {"mtcZ","moves a 4 byte value from a general purpose register to a Coprocessor Z Control register. Sign extension."}, 
  {"mthc1","move word to high half of floating point register"}, 
  {"mthc2","move word to high half of coprocessor 2 register"}, 
  {"mthi","move to hi register"}, 
  {"mtlo","move to lo register"}, 
  {"mul","multiply word to gpr"}, 
  {"mul.fmt","floating point multiply"}, 
  {"mult","int HI, int LO = (64-bit) $s * $t, trap on overflow"}, 
  {"multu","int HI, int LO = (64-bit) $s * $t"}, 
  {"neg.fmt","floating point negate"}, 
  {"nmadd.fmt","floating point negative multiply add"}, 
  {"nmsub.fmt","floating point negative multiply subtract"}, 
  {"nop","no operation"}, 
  {"nor","bitwise nor"}, 
  {"or","bitwise or"}, 
  {"ori","bitwise or, leftmost 16 bits are padded with 0s"}, 
  {"pll.ps","pair lower lower"}, 
  {"plu.ps","pair lower upper"}, 
  {"pref","prefetch"}, 
  {"prefx","prefetch indexed"}, 
  {"pul.ps","pair upper lower"}, 
  {"puu.ps","pair upper upper"}, 
  {"rdhwr","read hardware register"}, 
  {"rdpgpr","read gpr from previous shadow set"}, 
  {"recip.fmt","reciprocal approximation"}, 
  {"rotr","rotate word right"}, 
  {"rotrv","rotate word right variable"}, 
  {"round.l.fmt","floating point round to long fixed point"}, 
  {"round.w.fmt","floating point round to word fixed point"}, 
  {"rsqrt.fmt","reciprocal square root approximation"}, 
  {"sb","sb $t,C($s), stores the least-significant 8-bit of a register (a byte) into: MEM[$s+C]."}, 
  {"sc","store a word to memory."}, 
  {"scd","store conditional doubleword"}, 
  {"sdbbp","software debug breakpoint"}, 
  {"sdc1","store doubleword from floating point"}, 
  {"sdc2","store doubleword from coprocessor 2"}, 
  {"sdi","store doubleword"}, 
  {"sdl","store doubleword left"}, 
  {"sdr","store doubleword right"}, 
  {"sdxc1","store doubleword indexed from floating point"}, 
  {"seb","sign-extend byte"}, 
  {"seh","sign-extend halfword"}, 
  {"sh","sh $t,C($s), stores the least-significant 16-bit of a register (a halfword) into: MEM[$s+C]."}, 
  {"sll","sll $d,$t,shamt, shifts shamt number of bits to the left (multiply but 2^n)"}, 
  {"sllv","sllv $d,$t,$s, shifts $s number of bits to the left"}, 
  {"slt","tests if one register is less than another."}, 
  {"slti","tests if one register is less than a constant."}, 
  {"sltiu","set on less than immediate unsigned"}, 
  {"sltu","tests if one register is less than an unsigned constant."}, 
  {"sqrt.fmt","floating point square root"}, 
  {"sra","sda $d,$t,shamt, shifts shamt number of bits - the sign bit is shifted in"}, 
  {"srav","srav $d,$t,$s, shifts $s number of bits - the sign bit is shifted in"}, 
  {"srl","srl $d,$t,shamt, shifts shamt number of bits to the right - zeros are shifted in."}, 
  {"srlv","srlv $d,$t,$s, shifts $s number of bits to the right - zeros are shifted in"}, 
  {"ssnop","superscalar no operation"}, 
  {"sub","subtracts two registers, trap on overflow"}, 
  {"sub.fmt","floating point subtract"}, 
  {"subu","subtracts two registers"}, 
  {"suxc1","store doubleword indexed unaligned from floating point"}, 
  {"sw","sw $t,C($s), stores a word into: MEM[$s+C] and the following 3 bytes."}, 
  {"swc1","store word from floating point"}, 
  {"swc2","store word from coprocessor 2"}, 
  {"swl","store word left"}, 
  {"swr","store word right"}, 
  {"swxc1","store word indexed from floating point"}, 
  {"sync","synchronize shared memory"}, 
  {"synci","synchronize caches to make instruction writes effective"}, 
  {"syscall","system call"}, 
  {"teq","trap if equal"}, 
  {"teqi","trap if equal immediate"}, 
  {"tge","trap if greater or equal"}, 
  {"tgei","trap if greater or equal immediate"}, 
  {"tgeiu","trap if greater or equal immediate unsigned"}, 
  {"tgeu","trap if greater or equal unsigned"}, 
  {"tlbp","probe tlb for matching entry"}, 
  {"tlbr","read indexed tlb entry"}, 
  {"tlbwi","write indexed tlb entry"}, 
  {"tlbwr","write random tlb entry"}, 
  {"tlt","trap if less than"}, 
  {"tlti","trap if less than immediate"}, 
  {"tltiu","trap if less than immediate unsigned"}, 
  {"tltu","trap if less than unsigned"}, 
  {"tne","trap if not equal"}, 
  {"tnei","trap if not equal immediate"}, 
  {"trunc.l.fmt","floating point truncate to long fixed point"}, 
  {"trunc.w.fmt","floating point truncate to word fixed point"}, 
  {"wait","enter standby mode"}, 
  {"wrpgpr","write to gpr in previous shadow set"}, 
  {"wsbh","word swap bytes within halfwords"}, 
  {"xor","bitwise xor"}, 
  {"xori","bitwise xor with a constant"}, 
  {NULL, NULL}
};
// 0x47f5f8
// TODO
typedef int (*GperfForeachCallback)(void *user, const char *k, const char *v);
int gperf_mips_foreach(GperfForeachCallback cb, void *user) {
  int i = 0; while (kvs[i].name) {
  cb (user, kvs[i].name, kvs[i].value);
  i++;}
  return 0;
}
const char *gperf_mips_get(const char *s) {
  int i = 0; while (kvs[i].name) {
  if (!strcmp (s, kvs[i].name)) return kvs[i].value;
  i++;}
  return NULL;
}
#define sdb_hash_c_mips(x,y) gperf_mips_hash(x)
const unsigned int gperf_mips_hash(const char *s) {
  int sum = strlen (s);
  while (*s) { sum += *s; s++; }
  return sum;
}
struct {const char *name;void *get;void *hash;void *foreach;} gperf_mips = {
  .name = "mips",
  .get = &gperf_mips_get,
  .hash = &gperf_mips_hash,
  .foreach = &gperf_mips_foreach
};

#if MAIN
int main () {
	const char *s = ((char*(*)(char*))gperf_mips.get)("foo");
	printf ("%s\n", s);
}
#endif
