Source file: /~heha/hsn/gputils64-210929.zip/libgputils/gpregister.cpp

/* gpregister.c - Handler of the processor registers and bits.
   Copyright 2014	Molnár Károly
*/

#include "stdhdr.h"
#include "libgputils.h"

/*------------------------------------------------------------------------------------------------*/

int _cdecl gp_register_table_t::_mcu_cmp(const void *P1, const void *P2) {
  const char *n1 = reinterpret_cast<const char*>(P1),
	     *n2 = reinterpret_cast<const gp_register_table_t*>(P2)->name;
  return strcasecmp(n1,n2);
}

const gp_register_table_t* gp_register_table_t::find_mcu(const char *McuName) {
  return (const gp_register_table_t*)bsearch(McuName,
	gp_register_db, gp_register_db_size,
	sizeof(gp_register_table_t), _mcu_cmp);
}

/*------------------------------------------------------------------------------------------------*/

const gp_register_t* gp_register_table_t::find_reg(unsigned Address) const{
// No bsearch as table is possibly not sorted and zero-terminated
// TODO: Similar PICs should inherit their registers somehow!
  for (const gp_register_t**pp=registers;*pp;pp++) {
    const gp_register_t*p = *pp;
    unsigned sz = 1;		// size of register in bytes (span)
    if (p->mask&0xFF00) sz=2;	// word with "L" and "H"
// TODO: Decode other special meanings of mask
    if (p->addr<=Address && Address<p->addr+sz) return p;
  }
  return 0;
}

/*------------------------------------------------------------------------------------------------*/

const char* gp_register_table_t::find_reg_name(unsigned Address) const {
  const gp_register_t*r = find_reg(Address);
  if (!r) return 0;
  if (r->mask&0xFF00) {	// name must be synthesized
    size_t l = strlen(r->name);
    char*s = new char[l+2];
    memcpy(s,r->name,l);
    s[l] = "LHU"[Address-r->addr];	// append right suffix
    s[l+1] = 0;
    return s;		// TODO: Solve string allocation problem
  }			// TODO: Do other syntheses
  return r->name;
}

/*------------------------------------------------------------------------------------------------*/

static int _cdecl _bit_cmp(const void *P1, const void *P2) {
  int a1 = *reinterpret_cast<const unsigned*>(P1),
      a2 = reinterpret_cast<const gp_bit_t*>(P2)->address;
  return a1-a2;	// no overflow here
}

const char* gp_register_t::bit_name(unsigned Address) const {
  assert(Address<16);
  size_t bit_number = reinterpret_cast<size_t>(bitstring);
  if (bit_number>16) {	// compact bit description requiring string format
    const char*s = bitstring;
    if (!(1<<Address&mask)) return 0;	// For that register, that bit is not available
// This string terminates each bit group with "\1" (1) upto "\10" (8), its bit count.
// In case of multiple bits, bit number is appended, relative ("\2".."\10"),
// adding 8 ("\12".."20"), adding 16 ("\22".."30") or adding 24 ("\32.."40").
// In case of given mask, the string can be simply zero-terminated, and a bit number is always added.
// For possible 16-bit values, mask is expected to have 16 bit, but for now only 8 bits.
    unsigned a = Address;	// "relative" address
    do {
      const char*e = s;
      while ((unsigned char)*e>' ') ++e;	// search terminator
      unsigned n = *e;
      if (!n) n=16;		// expect a byte (?)
      unsigned k = (n-1)>>3;	// upper two bits control bit number insertion
      n = (n-1&7)+1;		// lower three bits = group length
      if (a<n) {		// right bit group
        if (s==e) return 0;	// empty bit name = no name
	unsigned z = a+(k<<3);	// add 0 / 8 / 16 / 24
	assert(z<100);		// 2 digits maximum
	bool app = z||n>1;	// append bit number?
	char*r = new char[e-s+(app?z>=10?3:2:1)];
	memcpy(r,s,e-s);	// copy name without terminator
	if (app) sprintf(r+(e-s),"%u",z);	// append bit number (0..23)
	else r[e-s]=0;		// don't append
	return r;		// return allocated string. BUG: Don't know how to deallocate yet.
      }
      a -= n;
      s = e;
    }while(*s);
    return 0;			// Address too large = no name
  }
  const gp_bit_t *ret = (const gp_bit_t*)bsearch(&Address, bits, bit_number, sizeof(gp_bit_t), _bit_cmp);
  return ret ? ret->name : 0;
}
Detected encoding: UTF-80