Reputation:
I have a struct of values:
struct Inst
{
int opc;
int opc2;
int opc3;
int imm;
int imm2;
int rs1;
int rs2;
int rd;
};
For each value, I want there to be a corresponding string that represents that value. So if opc = 0x3
, then its corresponding string would be "OP-IMM"
. So value can be an input that I know of. It's just a matter of mapping that value to its corresponding string. Functionally, this would look like so:
printf("%s", lookup(opc)) // If the value is 0x37, then it prints LUI, if it's 0x6F, then it prints JAL etc...
How would I do that?
Upvotes: 0
Views: 566
Reputation: 1432
The following code does, what you want...I am assuming you don't have much instructions. If you've much more instruction like a Million, you should use Balanced Binary Search Tree
instead of array
.(note: I am using linear search to find matching key with an average search complexity of O(n) for each search).
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int *keys; // this to hold keys
char **vals; // this to hold valsues or strings
int size;
int capacity;
} Table;
Table *getTable(int capacity) {
Table *table = (Table *)malloc(sizeof(Table));
table->keys = malloc(sizeof(int) * capacity);
table->vals = malloc(sizeof(char *) * capacity);
table->size = 0;
table->capacity = capacity;
return table;
}
int insert(Table *table, int key, char *val) {
if(table->size >= table->capacity) {
// couldn't add more key/val pairs
// capacity overflowed
return 0;
}
// copy val into new dymanic char array string
int l = strlen(val);
char *buf = malloc(sizeof(char) * (l+1)); // l+1 for null char at the end
strcpy(buf, val);
table->keys[table->size] = key;
table->vals[table->size] = val;
table->size++;
return 1; // key/val pair add is successful
}
char *lookup(Table *table, int key) {
for(int i=0; i<table->size; i++) {
if(table->keys[i] == key) {
return table->vals[i];
}
}
return NULL;
}
void destroyTable(Table *table) {
for(int i=0; i<table->size; i++) {
free(table->vals[i]);
}
free(table->keys);
free(table->vals);
free(table);
}
int main() {
int capacity = 10;
Table *table = getTable(capacity);
int k1 = 12;
char *v1 = "hello";
int k2 = 19;
char *v2 = "world!";
insert(table, k1, v1);
insert(table, k2, v2);
char *val = lookup(table, k1);
printf("%d: %s\n", k1, val);
val = lookup(table, k2);
printf("%d: %s\n", k2, val);
destroyTable(table);
return 0;
}
And the output for my input was:
12: hello
19: world!
which ensures that it works properly.
Also, note I've used decimal integer. For use hexadecimal you could as follows:
int key = 0x37;
And you're done...
[P.S.]: feel free to ask if anything is unclear.
Upvotes: 0
Reputation: 4537
If you have few numbers (few is relative; actually can be a million easily without problems, depending on the system), and a numbering where all of the possible numbers in a valid range have a meaning, or at least most of them, you can have a simple array.
Let's have the following codes table:
0x0: invalid
0x1: "aaa"
0x2: "bbb"
0x3: "ccc"
0x4: invalid
0x5: "ddd"
An easy and efficient way to build a lookup table is the following:
const char lut[6][MAX_STRINGLEN + 1] = {
NULL, "aaa", "bbb", "ccc", NULL, "ddd"
};
And use the string simply by calling the array at the index of the code lut[opcode]
.
In C2x (the next revision of the standard), there is a way to initialize the array with a binary file, which if the array size is very big, can mean a significant improvement in compilation time.
Upvotes: 0