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

struct kv { const char *name; const char *value; };
static struct kv kvs[] = {
  {"adc","add with carry"}, 
  {"adcs","add with carry and update flags"}, 
  {"add","add two values"}, 
  {"addeq","add two values if Z set (equal)"}, 
  {"addlo","add if C is clear (no carry)"}, 
  {"addne","add two values if Z clear (not equal)"}, 
  {"adds","add two values and update flags"}, 
  {"and","logical AND"}, 
  {"andeq","logical AND if Z set (equal)"}, 
  {"andne","logical AND if Z clear (not equal)"}, 
  {"ands","logical AND that updates flags"}, 
  {"asr","arithmetic shift right"}, 
  {"asrs","arithmetic shift right and update flags"}, 
  {"autiasp","authenticate return pointer before returning from function using A key"}, 
  {"autibsp","authenticate return pointer before returning from function using B key"}, 
  {"b","branches the program counter to dst (pc aka r15)"}, 
  {"bcc","branch if C clear (no carry)"}, 
  {"bcs","branch if C set (carry)"}, 
  {"beq","branches if equal (see 'b') Z is set"}, 
  {"bge","branch if N clear and V clear"}, 
  {"bgt","branch if Z, N and V clear"}, 
  {"bhi","branch if C set and Z clear"}, 
  {"bhs","variant of bcs"}, 
  {"bic","logical bit clear"}, 
  {"bics","Bitwise bit clear (shifted register), setting the condition flags."}, 
  {"bics.w","word bitwise bit clear and update flags"}, 
  {"bl","branches and link, similar to call in i386, set lr(r14) = pc, changes pc (r15) )"}, 
  {"ble","branch if (Z || (N && V)) or !N && V) or !N && V"}, 
  {"blo","variant of bcc"}, 
  {"blraa","brank and link with pointer authentication"}, 
  {"blraaz","variants of blraa"}, 
  {"blrab","variants of blraa"}, 
  {"blrabz","variants of blraa"}, 
  {"bls","branch if C clear or Z set"}, 
  {"blt","branch if N clear and V set"}, 
  {"blx","branch link and optionally exchange to Thumb"}, 
  {"bmi","branch if N set"}, 
  {"bne","branch if Z clear (not equal)"}, 
  {"bpl","branch if N clear"}, 
  {"braa","branch with pointer authentication using A key"}, 
  {"braaz","variant of braa"}, 
  {"brab","branch with pointer authentication using B key"}, 
  {"brabz","variant of brabz"}, 
  {"bvc","branch if V clear"}, 
  {"bvs","branch if V set"}, 
  {"bx","branches and exchanges cpu mode to 16 bits (thumb mode)"}, 
  {"bxj","branches and exchanges cpu mode to Jazzele (jumps to a bytecode vector)"}, 
  {"cbnz","compare and branch on non-zero"}, 
  {"cbz","compare and branch on zero"}, 
  {"cdp","coprocessor data operations"}, 
  {"cmn","compare negated"}, 
  {"cmp","compares two registers"}, 
  {"cps","change processor state"}, 
  {"cpsid","like msr, but only disable interrupts (i or f)"}, 
  {"cpsie","like msr, but only enable interrupts (i or f)"}, 
  {"dc","data cache operation (alias of sys)"}, 
  {"dsb","data synchronization barrier."}, 
  {"eor","logical exclusive OR (XOR)"}, 
  {"eoreq","logical exclusive OR (XOR) if Z set (equal)"}, 
  {"eorne","logical exclusive OR (XOR) if Z clear (not equal)"}, 
  {"eors","logical exclusive OR (XOR) and update flags"}, 
  {"eret","return from exception"}, 
  {"flt","armfpu: convert int to float: flt "}, 
  {"hlt","external debug breakpoint."}, 
  {"hvc","hypervisor call"}, 
  {"ic","instruction cache operation (alias of sys)"}, 
  {"isb","instruction synchronization barrier."}, 
  {"it","if then"}, 
  {"ldc","load from memory to coprocessor"}, 
  {"ldf","armfpu: load float value pointed by reg+(offset): ldf f0, [r0,#off]"}, 
  {"ldm","load to multiple registers from memory"}, 
  {"ldm.w","load multiple words from memory into registers"}, 
  {"ldmda","decrement after"}, 
  {"ldmdb","decrement before"}, 
  {"ldmia","incrememnt after"}, 
  {"ldmib","increment before"}, 
  {"ldp","load a pair of registers from memory"}, 
  {"ldr","load from memory to register"}, 
  {"ldr.w","load from memory to register"}, 
  {"ldraa","load from memory to register authenticanting the pointer using A key"}, 
  {"ldrab","load from memory to register authenticanting the pointer using B key"}, 
  {"ldrb","load byte from memory to register"}, 
  {"ldrb.w","load from memory to register"}, 
  {"ldreq","load from memory to register if Z set (equal)"}, 
  {"ldrh","load half word (16bit) from memory to register"}, 
  {"ldrne","load from memory to register if Z clear (not equal)"}, 
  {"lsl","logical shift left"}, 
  {"lsls","logical shift left and update flags"}, 
  {"lsr","logical shift right"}, 
  {"lsrs","logical shift right and update flags"}, 
  {"mcr","move to coprocessor from ARM register"}, 
  {"mcrr","move to coprocessor from two ARM register"}, 
  {"mla","multiply and accumulate"}, 
  {"mls","multiply and substract"}, 
  {"mov","move value between registers"}, 
  {"mov.w","move 3byte immediate into register"}, 
  {"movs","move immediate into register and update flags"}, 
  {"movt","write 16 bit value on top of halfword"}, 
  {"movw","write 16 bit value on lower bits"}, 
  {"movz","move shifted 16-bit immediate to register."}, 
  {"mul","multiply"}, 
  {"mvn","move bitwise NOT"}, 
  {"mvns","move bitwise NOT and update flags"}, 
  {"orr","logical inclusive OR"}, 
  {"orreq","logical inclusive OR if Z set (equal)"}, 
  {"orrne","logical inclusive OR if Z clear (not equal)"}, 
  {"orrs","logical inclusive OR and update flags"}, 
  {"paciasp","function prelude for pointer authentication using A key"}, 
  {"pacibsp","function prelude for pointer authentication using B key"}, 
  {"pop","load N elements from stack into given registers"}, 
  {"pop.w","load N words from stack into registers"}, 
  {"retaa","return with authenticated pointer using A key"}, 
  {"retab","return with authenticated pointer using B key"}, 
  {"rfe","return from exception (loads pc+cpsr)"}, 
  {"rsb","reverse substract"}, 
  {"rsbs","subtracts the value from zero, producing the arithmetic negative of the value, and updates flags"}, 
  {"rsbs.w","substract the negative value"}, 
  {"rsc","reverse substract with carry"}, 
  {"sbc","substract with carry"}, 
  {"sbfx","signed bit field extract"}, 
  {"sdiv","signed division"}, 
  {"srs","store return state"}, 
  {"stadd","atomic add word (arm v8.1)"}, 
  {"staddl","atomic add dword (arm v8.1)"}, 
  {"stc","store from coprocessor to memory"}, 
  {"stf","armfpu: store float value pointed by reg+(offset): ldf [r0,#off]"}, 
  {"stm","store multiple registers to memory"}, 
  {"stp","store register pairs in memory"}, 
  {"str","store register into memory"}, 
  {"strb","store byte value in register into memory"}, 
  {"strb.w","store byte value in register into memory"}, 
  {"strd","store floating point value in memory"}, 
  {"streq","store register into memory if Z set (equal)"}, 
  {"strh","store byte value in register into memory"}, 
  {"strh.w","store byte value in register into memory"}, 
  {"strne","store register into memory if Z clear (not equal)"}, 
  {"sub","substract two values"}, 
  {"subeq","substract two values if Z set (equal)"}, 
  {"subne","substract two values if Z clear (not equal)"}, 
  {"subs","substract two values and update flags"}, 
  {"svc","supervisor call"}, 
  {"sxtb","extracts bits[7:0] and sign extends to 32 bits."}, 
  {"sxth","extracts bits[15:0] and sign extends to 32 bits."}, 
  {"sxtw","signed extend word"}, 
  {"teq","test equivalence"}, 
  {"tst","test"}, 
  {"tst.w","logical AND register value with 12-bit immediate value"}, 
  {"ubfx","unsigned bit field extract"}, 
  {"udiv","unsigned division"}, 
  {"uxtab","zero extend Byte and Add. Extends an 8-bit value to a 32-bit value."}, 
  {"uxtab16","zero extend bytes to halfwords add halfwords"}, 
  {"uxtb","extracts bits[7:0] and zero extends to 32 bits."}, 
  {"uxtb.w","zero textend word and add, extend to 32bit value"}, 
  {"uxth","extracts bits[15:0] and zero extends to 32 bits."}, 
  {"vadd","vector add"}, 
  {"vldmia","vector load memory into paired registers"}, 
  {"vsri","vector shift right and insert"}, 
  {"wfe","wait for event"}, 
  {"wfi","wait for interrupt"}, 
  {"wfs","armfpu: write fp status register. wfs r0"}, 
  {"xpacd","strip pac from data pointer"}, 
  {"xpaci","strip pac from instruction pointer"}, 
  {"xpaclri","system strip pointer authentication"}, 
  {"yield","alias for hint instructrion"}, 
  {NULL, NULL}
};
// 0x451e58
// TODO
typedef int (*GperfForeachCallback)(void *user, const char *k, const char *v);
int gperf_arm_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_arm_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_arm(x,y) gperf_arm_hash(x)
const unsigned int gperf_arm_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_arm = {
  .name = "arm",
  .get = &gperf_arm_get,
  .hash = &gperf_arm_hash,
  .foreach = &gperf_arm_foreach
};

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