Commit 6973fc1b authored by sea19's avatar sea19
Browse files

NEW MACRO FILE ADDED, code looks cleaner

parent 21cc3885
......@@ -6,13 +6,13 @@ ASSEMBLEFILES = assemble.c assemble_utils.c
all: emulate assemble
assemble: assemble.o assemble_utils.o
$(CC) $(CFLAGS) $(ASSEMBLEFILES) -o assemble
emulate: emulate.o fetch.o decode.o execute.o instrType.o
$(CC) $(CFLAGS) $(EMULATEFILES) -o emulate
assemble: assemble.o assemble_utils.o
$(CC) $(CFLAGS) $(ASSEMBLEFILES) -o assemble
clean:
rm -f $(wildcard *.o)
rm -f assemble
rm -f emulate
rm -f assemble
......@@ -2,10 +2,7 @@
#include <stdint.h>
#include <string.h>
#include "assemble_utils.h"
//return statements not included yet..
//need way to calculate Operand2..
//need to make way to read registers..
//special instructions TODO..
#include "macrosAndStructs.h"
static const char *mnemonicsList[] = {
"add", "sub", "rsb", "and", "eor", "orr", "mov", "tst", "teq", "cmp", "mul",
......@@ -14,14 +11,14 @@ static const char *mnemonicsList[] = {
int findLabel(FILE *srcFile, char *label, int currentAddress) {
int i = 0;
char *buffer = calloc(50, sizeof(char));
char *buffer = calloc(MAX_LENGTH_OF_LINE, sizeof(char));
rewind(srcFile);
label[strlen(label) - 1] = '\0';
char *colon = ":\n";
strcat(label, colon);
while (fgets(buffer, 50, srcFile)) {
while (fgets(buffer, MAX_LENGTH_OF_LINE, srcFile)) {
if (strcmp(buffer, label) == 0) {
return i - currentAddress - 8;
return i - currentAddress - PC_OFFSET;
}
if (buffer[strlen(buffer) - 2] != ':') {
i += 4;
......@@ -32,8 +29,8 @@ int findLabel(FILE *srcFile, char *label, int currentAddress) {
int getNoOfInstructions(FILE *srcFile) {
int result = 0;
char *buffer = calloc(50, sizeof(char));
while (fgets(buffer, 50, srcFile)) {
char *buffer = calloc(MAX_LENGTH_OF_LINE, sizeof(char));
while (fgets(buffer, MAX_LENGTH_OF_LINE, srcFile)) {
int len = strlen(buffer);
if (buffer[len - 2] != ':') {
result++;
......@@ -46,10 +43,10 @@ void second_pass(FILE *srcFile, FILE *dstFile) {
int currentAddress = 0;
int noOfInstructions = getNoOfInstructions(srcFile);
rewind(srcFile);
char *buffer = calloc(50, sizeof(char));
int *storedValues = calloc(20, sizeof(char));
char *buffer = calloc(MAX_LENGTH_OF_LINE, sizeof(char));
int *storedValues = calloc(MAX_LENGTH_OF_LINE, sizeof(char));
memset(buffer, 0, sizeof(char) * sizeof(buffer));
while (fgets(buffer, 50, srcFile)) {
while (fgets(buffer, MAX_LENGTH_OF_LINE, srcFile)) {
int len = strlen(buffer);
if (buffer[len - 2] != ':' && *buffer != '\n') {
int instruction = 0;
......@@ -75,7 +72,6 @@ void setBitAtPos(int pos, int value, int *number) {
}
int generateBinary(char *buffer, int *storedValues, int currentAddress, int noOfInstructions, FILE *srcFile) {
//int len = strlen(buffer);
char *sep = " ,", *token = strtok(buffer, sep), operands[6][20];
memset(operands, 0, sizeof(operands));
int mnemonic = findMnemonic(token), noOperands = 0;
......@@ -93,7 +89,7 @@ int generateBinary(char *buffer, int *storedValues, int currentAddress, int noOf
return assembleMultiply(mnemonic, operands);
}
if (mnemonic < BEQ) {
return assembleSIngleDataTransfer(mnemonic, operands, storedValues, noOfInstructions, currentAddress);
return assembleSingleDataTransfer(mnemonic, operands, storedValues, noOfInstructions, currentAddress);
}
if (mnemonic < LSLOP) {
return assembleBranch(mnemonic, operands, srcFile, currentAddress);
......@@ -103,7 +99,7 @@ int generateBinary(char *buffer, int *storedValues, int currentAddress, int noOf
int findMnemonic(char *p) {
int i;
for (i = 0; i <= 22; i++) {
for (i = 0; i < NUM_OF_MNENMONICS; i++) {
if (!strcmp(p, mnemonicsList[i])) {
return i;
}
......@@ -118,15 +114,15 @@ int getOperand2(char operands[20]) {
} else {
result = atoi(operands + 1);
}
if (result < 256) {
if (result < MAX_LDR_USED_AS_MOV) {
return result;
} else {
int x = 16;
while(result > 255 || ((result & 3) == 0)) {
result = (result >> 2);
int x = MAX_NO_OF_ROTATIONS;
while(result > 0xFF || ((result & 3) == 0)) {
result = (result >> ONE_ROTATION);
x--;
}
result |= (x << 8);
result |= (x << ROTATE_BIT);
return result;
}
}
......@@ -139,8 +135,8 @@ int isImmediate(char operands[20]) {
}
int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, opCode, cond = 14; //14 = 1110
setBitAtPos(28, cond, &result);
int result = 0, opCode, cond = COND_AL; //14 = 1110
setBitAtPos(COND_BIT, cond, &result);
if (mnemonic >= ADD && mnemonic <= ORR) {
switch (mnemonic) {
case ADD:
......@@ -165,27 +161,27 @@ int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]) {
perror("Invalid mnemonic");
}
int rd = atoi(operands[0] + 1), rn = atoi(operands[1] + 1);
setBitAtPos(21, opCode, &result);
setBitAtPos(16, rn, &result);
setBitAtPos(12, rd, &result);
setBitAtPos(DATA_PROCESS_OPCODE_BIT, opCode, &result);
setBitAtPos(DATA_PROCESS_RN_BIT, rn, &result);
setBitAtPos(DATA_PROCESS_RD_BIT, rd, &result);
int operand2 = getOperand2(operands[2]);
int immediate = isImmediate(operands[2]);
setBitAtPos(25, immediate, &result);
setBitAtPos(DATA_PROCESS_I_BIT, immediate, &result);
setBitAtPos(0, operand2, &result);
return result;
}
if (mnemonic == MOV) {
int rd = atoi(operands[0] + 1);
opCode = 13; //1101
setBitAtPos(21, opCode, &result);
setBitAtPos(12, rd, &result);
setBitAtPos(DATA_PROCESS_OPCODE_BIT, opCode, &result);
setBitAtPos(DATA_PROCESS_RD_BIT, rd, &result);
int operand2 = getOperand2(operands[1]);
int leftShift = 0;
if (strcmp(operands[2], "lsl") == 0) {
if (!strcmp(operands[2], "lsl")) {
leftShift = getOperand2(operands[3]);
}
int immediate = isImmediate(operands[1]);
setBitAtPos(25, immediate, &result);
setBitAtPos(DATA_PROCESS_I_BIT, immediate, &result);
setBitAtPos(0, operand2, &result);
setBitAtPos(7, leftShift, &result);
return result;
......@@ -206,42 +202,42 @@ int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]) {
int rn = atoi(operands[0] + 1);
int operand2 = getOperand2(operands[1]);
int immediate = isImmediate(operands[1]);
setBitAtPos(25, immediate, &result);
setBitAtPos(DATA_PROCESS_I_BIT, immediate, &result);
setBitAtPos(0, operand2, &result);
setBitAtPos(20, 1, &result);
setBitAtPos(21, opCode, &result);
setBitAtPos(16, rn, &result);
setBitAtPos(DATA_PROCESS_S_BIT, 1, &result);
setBitAtPos(DATA_PROCESS_OPCODE_BIT, opCode, &result);
setBitAtPos(DATA_PROCESS_RN_BIT, rn, &result);
return result;
}
int assembleMultiply(enum mnemonics mnemonic, char operands[6][20]) {
int result = 0, cond = 14, mask = 9;
int result = 0, cond = COND_AL, mask = 9;
int rd = atoi(operands[0] + 1), rs = atoi(operands[2] + 1);
int rm = atoi(operands[1] + 1); //1110, 1001
setBitAtPos(28, cond, &result);
setBitAtPos(16, rd, &result);
setBitAtPos(8, rs, &result);
setBitAtPos(COND_BIT, cond, &result);
setBitAtPos(MUL_RD_BIT, rd, &result);
setBitAtPos(MUL_RS_BIT, rs, &result);
setBitAtPos(4, mask, &result);
setBitAtPos(0, rm, &result);
if (mnemonic == MLA) {
int rn = atoi(operands[3] + 1);
setBitAtPos(12, rn, &result);
setBitAtPos(21, 1, &result);
setBitAtPos(MUL_RN_BIT, rn, &result);
setBitAtPos(MUL_ACC_BIT, 1, &result);
}
return result;
}
int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20], int *storedValues, int noOfInstructions, int pc) {
int result = 0, cond = 14, offset; //1110
int assembleSingleDataTransfer(enum mnemonics mnemonic, char operands[6][20], int *storedValues, int noOfInstructions, int pc) {
int result = 0, cond = COND_AL, offset; //1110
int rd = atoi(operands[0] + 1);
setBitAtPos(12, rd, &result);
setBitAtPos(28, cond, &result);
setBitAtPos(SINGLEDATA_RD_BIT, rd, &result);
setBitAtPos(COND_BIT, cond, &result);
if (mnemonic == LDR) {
if (operands[1][0] == '=') {
int operand2 = (int) strtol(operands[1] + 1, NULL, 0);
if (operand2 < (1 << 12)) {
setBitAtPos(25, 1, &result);
setBitAtPos(21, 13, &result);
setBitAtPos(DATA_PROCESS_I_BIT, 1, &result);
setBitAtPos(DATA_PROCESS_OPCODE_BIT, 13, &result);
setBitAtPos(0, operand2, &result);
return result;
} else {
......@@ -253,46 +249,46 @@ int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20], in
storedValues[i] = operand2;
offset = (noOfInstructions - (pc / 4) + i - 2) * 4 ;
setBitAtPos(0, offset, &result);
setBitAtPos(20, 1, &result);
setBitAtPos(24, 1, &result);
setBitAtPos(SINGLEDATA_LOAD_BIT, 1, &result);
setBitAtPos(SINGLEDATA_P_BIT, 1, &result);
setBitAtPos(26, 1, &result);
setBitAtPos(20, 1, &result);
setBitAtPos(23, 1, &result);
setBitAtPos(16, 15, &result);
setBitAtPos(SINGLEDATA_LOAD_BIT, 1, &result);
setBitAtPos(SINGLEDATA_UP_BIT, 1, &result);
setBitAtPos(SINGLEDATA_RN_BIT, 15, &result);
return result;
}
}
}
setBitAtPos(26, 1, &result);
if (mnemonic == LDR) {
setBitAtPos(20, 1, &result);
setBitAtPos(SINGLEDATA_LOAD_BIT, 1, &result);
}
int rn = atoi(operands[1] + 2);
setBitAtPos(16, rn, &result);
setBitAtPos(SINGLEDATA_RN_BIT, rn, &result);
if (operands[1][3] == ']' && !operands[2][0]) {
offset = 0;
setBitAtPos(24, 1, &result);
setBitAtPos(23, 1, &result);
setBitAtPos(SINGLEDATA_P_BIT, 1, &result);
setBitAtPos(SINGLEDATA_UP_BIT, 1, &result);
} else {
if (operands[2][0] == '#') {
setBitAtPos(24, 1, &result);
setBitAtPos(SINGLEDATA_P_BIT, 1, &result);
if (operands[2][2] == 'x') {
offset = (int) strtol(operands[2] + 1, NULL, 0); //Converts a hex string into an integer
setBitAtPos(23, 1, &result);
setBitAtPos(SINGLEDATA_UP_BIT, 1, &result);
} else if (operands[2][3] == 'x' && operands[2][1] == '-') {
offset = (int) strtol(operands[2] + 2, NULL, 0);
} else {
offset = atoi(operands[2] + 1);
setBitAtPos(23, 1, &result);
setBitAtPos(SINGLEDATA_UP_BIT, 1, &result);
}
setBitAtPos(0, offset, &result);
} else {
offset = atoi(operands[2] + 1);
if (operands[2][strlen(operands[2]) - 2] == ']') {
setBitAtPos(24, 1, &result);
setBitAtPos(SINGLEDATA_P_BIT, 1, &result);
}
setBitAtPos(23, 1, &result);
setBitAtPos(25, 1, &result);
setBitAtPos(SINGLEDATA_UP_BIT, 1, &result);
setBitAtPos(SINGLEDATA_I_BIT, 1, &result);
setBitAtPos(0, offset, &result);
}
}
......@@ -300,7 +296,7 @@ int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20], in
}
int assembleBranch(enum mnemonics mnemonic, char operands[6][20], FILE *srcFile, int currentAddress) {
int result = 0, cond = 14, mask = 5, offset; //1110, 101
int result = 0, cond = COND_AL, mask = 5, offset; //1110, 101
if (mnemonic >= BEQ && mnemonic <= B) {
switch (mnemonic) {
case BEQ:
......@@ -328,13 +324,13 @@ int assembleBranch(enum mnemonics mnemonic, char operands[6][20], FILE *srcFile,
perror("Invalid mnemonic");
}
}
setBitAtPos(28, cond, &result);
setBitAtPos(COND_BIT, cond, &result);
setBitAtPos(25, mask, &result);
int temp = ftell(srcFile);
offset = findLabel(srcFile, operands[0], currentAddress);
if (offset < 0) {
offset = offset >> 2;
offset &= 0x00ffffff;
offset &= 0x00ffffff; //Converts offset into signed 24 bit integer
}
setBitAtPos(0, offset, &result);
fseek(srcFile, temp, SEEK_SET);
......
......@@ -20,7 +20,7 @@ int assembleDataProcessing(enum mnemonics mnemonic, char operands[6][20]);
int assembleMultiply(enum mnemonics mnemonic, char operands[6][20]);
int assembleSIngleDataTransfer(enum mnemonics mnemonic, char operands[6][20], int *storedValues, int noOfInstructions, int pc);
int assembleSingleDataTransfer(enum mnemonics mnemonic, char operands[6][20], int *storedValues, int noOfInstructions, int pc);
int assembleBranch(enum mnemonics mnemonic, char operands[6][20], FILE *srcFile, int currentAddress);
......
#include "decode.h"
void decode(unsigned int instruction, decoded *decodedInstr) {
unsigned int bit26and27 = (instruction >> 26) & 3;
decodedInstr->condition = (instruction >> 28) & 0xf;
decodedInstr->bit0to25 = (instruction) & 0x3ffffff;
if (bit26and27 == 0) {
if (((instruction >> 22) & 0xf) == 0 && ((instruction >> 4) & 0xf) == 9) {
decodedInstr->type = multiply;
} else {
findOpcode(decodedInstr, instruction);
}
} else if (bit26and27 == 1) {
decodedInstr->type = singledata;
} else if (bit26and27 == 2) {
decodedInstr->type = branch;
}
}
#include "macrosAndStructs.h"
void findOpcode(decoded *decodedInstr, unsigned int instruction) {
unsigned int opcode = (instruction >> 21) & 0xf;
......@@ -44,3 +25,22 @@ void findOpcode(decoded *decodedInstr, unsigned int instruction) {
decodedInstr->type = mov;
}
}
void decode(unsigned int instruction, decoded *decodedInstr) {
unsigned int bit26and27 = (instruction >> 26) & 3;
decodedInstr->condition = (instruction >> COND_BIT) & 0xf;
decodedInstr->bit0to25 = (instruction) & 0x3ffffff;
if (bit26and27 == 0) {
if (((instruction >> 22) & 0xf) == 0 && ((instruction >> 4) & 0xf) == 9) {
decodedInstr->type = multiply;
} else {
findOpcode(decodedInstr, instruction);
}
} else if (bit26and27 == 1) {
decodedInstr->type = singledata;
} else if (bit26and27 == 2) {
decodedInstr->type = branch;
}
}
#ifndef DECODE_H
#define DECODE_H
typedef enum {and, eor, sub, rsb, add, tst, teq, cmp, orr, mov, multiply, branch, singledata}type;
typedef struct decoded {
type type;
unsigned int condition;
unsigned int bit0to25;
} decoded;
#include "macrosAndStructs.h"
void findOpcode(decoded *decodedInstr, unsigned int instruction); //Finds the opcode of a data processing instruction
......
......@@ -5,8 +5,7 @@
#include "decode.h"
#include "fetch.h"
#include "execute.h"
#include <math.h>
#include <time.h>
#include "macrosAndStructs.h"
void bigToLittleEndian(armstate *state) {
int temp;
......@@ -14,14 +13,11 @@ void bigToLittleEndian(armstate *state) {
temp = state->memory[j];
state->memory[j] = (temp & 0xff) << 24 | (temp & 0xff00) << 8 |
(temp & 0xff0000) >> 8 | (temp & 0xff000000) >> 24;
//Takes each value in the memory and flips it into little endian form
}
}
void printResult(armstate *state) {
//clock_t start, end;
//double timeTaken;
//start = clock();
#define INRANGE(x) (x < 0xc4653601) && (x >= 0x80000000)
void printResult(armstate *state) { //Prints the result to stdout
bigToLittleEndian(state);
printf("Registers:\n");
for (int i = 0; i < 13; i++) {
......@@ -47,9 +43,6 @@ void printResult(armstate *state) {
printf("0x%08x: 0x%08x\n", i * 4, state->memory[i]);
}
}
//end = clock();
//timeTaken = ((double)(end - start)) / CLOCKS_PER_SEC;
//printf("Time Taken for printing results: %f\n", timeTaken);
}
void startCycle(armstate *state) {
......@@ -59,24 +52,24 @@ void startCycle(armstate *state) {
bool finished = false;
unsigned int *objectcode = state->memory;
while(!finished) {
while(!finished) { //Start of the arm Pipeline
if (*pc == 0) {
fetched = fetch(objectcode, *pc/4);
*pc += 4;
} else if (*pc == 4) {
fetched = fetch(objectcode, *pc/WORDLENGTH);
*pc += WORDLENGTH;
} else if (*pc == WORDLENGTH) {
decode(fetched, decodedInstr);
fetched = fetch(objectcode, *pc/4);
*pc += 4;
fetched = fetch(objectcode, *pc/WORDLENGTH);
*pc += WORDLENGTH;
} else {
execute(decodedInstr, state);
if (decodedInstr->type == branch && do_next_instruction(decodedInstr,
state)) {
fetched = fetch(objectcode, *pc/4);
*pc += 4;
fetched = fetch(objectcode, *pc/WORDLENGTH);
*pc += WORDLENGTH;
}
decode(fetched, decodedInstr);
fetched = fetch(objectcode, *pc/4);
*pc += 4;
fetched = fetch(objectcode, *pc/WORDLENGTH);
*pc += WORDLENGTH;
if (decodedInstr->condition == 0 && decodedInstr->bit0to25 == 0 &&
decodedInstr->type == and){
finished = true;
......@@ -89,26 +82,19 @@ void startCycle(armstate *state) {
printResult(state);
free(decodedInstr);
} //pipeline
}
int main(int argc, char **argv) {
//clock_t start, end;
//double timeTaken;
//start = clock();
//unsigned int registers[NREGS];
armstate *state = (armstate *) calloc(1, sizeof(armstate));
armstate_init(state); // &??????????
armstate_init(state);
assert(argc == 2);
readFile(argv[1], state->memory);
startCycle(state); //???????
startCycle(state);
free(state->memory);
free(state);
//end = clock();
//timeTaken = ((double)(end - start)) / CLOCKS_PER_SEC;
//printf("Time Taken: %f\n", timeTaken);
return EXIT_SUCCESS;
}
#ifndef EMULATE_H
#define EMULATE_H
#define NREGS 17
#define STACK_SIZE 16384 //Defined stack as ints which are 4 bytes so (64*1024)/4
#define PC 15
void bigToLittleEndian(armstate *state);
void printResult(armstate *state, int numOfInstr);
......
#include "execute.h"
#include "macrosAndStructs.h"
#include "instrType.h"
#include <stdlib.h>
void armstate_init(armstate *state) {
/* zero out all arm state */
// zero out all arm state
state->n = 0;
state->z = 0;
state->c = 0;
......@@ -17,33 +18,30 @@ void armstate_init(armstate *state) {
// next_instruction_condition_check
int do_next_instruction(decoded *decodedInstr, armstate *state){
unsigned int cond = decodedInstr->condition;
int run_command;
if ((cond == 0) && (state->z == 1 )) { // cond in decimal?
run_command = 1;
} else if ((cond == 1) && (state->z == 0)) {
run_command = 1;
} else if ((cond == 10) && (state->n == state->v)) {
run_command = 1;
} else if ((cond == 11) && (state->n != state->v)) {
run_command = 1;
} else if (cond == 12 && state->z == 0 && state->n == state->v) {
run_command = 1;
} else if (cond == 13 && (state->z == 1 || state->n != state->v)) {
run_command = 1;
} else if (cond == 14){
run_command = 1;
} else {
run_command = 0;
}
return run_command;
if ((cond == COND_EQ) && state->z) return 1;
if ((cond == COND_NE) && !state->z) return 1;
if ((cond == COND_GE) && (state->n == state->v)) return 1;
if ((cond == COND_LT) && (state->n != state->v)) return 1;
if (cond == COND_GT && !state->z && state->n == state->v) return 1;
if (cond == COND_LE && (state->z || state->n != state->v)) return 1;
if (cond == COND_AL) return 1;
return 0;
}
//Operand2 is a register
void val_reg_last12bits(decoded *decodedInstr, unsigned int *operand2, armstate *state) {
unsigned int iw = decodedInstr -> bit0to25;
unsigned int val_in_rm = state -> regs[iw & 0xF]; // state -> regs[iw & 0xF] == Rm
unsigned int sh_op = (iw >> 4) & 1;
unsigned int sh_type = (iw >> 5) & 3;
unsigned int sh_op = (iw >> SHIFT_OP) & 1;
unsigned int sh_type = (iw >> SHIFT_TYPE) & 3;
unsigned int amount;
if(sh_op == 0){
amount = (iw >> 7) & 31;
......@@ -58,7 +56,7 @@ void val_reg_last12bits(decoded *decodedInstr, unsigned int *operand2, armstate
break;
case 2 : *operand2 = (signed) val_in_rm >> amount;
break;
case 3 : *operand2 = val_in_rm >> amount || ((val_in_rm & amount) << (32 - amount)); // ??????????
case 3 : *operand2 = val_in_rm >> amount || ((val_in_rm & amount) << (32 - amount));
break;
default :
exit(1);
......@@ -71,7 +69,7 @@ unsigned int shift_carry_out(decoded_dp *decodedDp, decoded *decodedInstr, armst
unsigned int sh_type, sh_op;
unsigned int iw = decodedInstr -> bit0to25;
immediate = (iw >> 25) & 1;
immediate = (iw >> SINGLEDATA_I_BIT) & 1;
if(immediate == 1){
amount = (iw >> 8) & 0xF;
val = (iw & 0xFF);
......@@ -101,10 +99,10 @@ void decode_data_processing(decoded *decodedInstr, decoded_dp *decodedDp, armsta
unsigned int immediate, iw, operand2;
iw = decodedInstr -> bit0to25;
decodedDp -> type = decodedInstr -> type;
decodedDp -> rd = (iw >> 12) & 0xF;
decodedDp -> rn = (iw >> 16) & 0xF;
decodedDp -> s_bit = (iw >> 20) & 1;
immediate = (iw >> 25) & 1;
decodedDp -> rd = (iw >> DATA_PROCESS_RD_BIT) & 0xF;
decodedDp -> rn = (iw >> DATA_PROCESS_RN_BIT) & 0xF;
decodedDp -> s_bit = (iw >> DATA_PROCESS_S_BIT) & 1;
immediate = (iw >> DATA_PROCESS_I_BIT) & 1;
if(immediate == 1){
......
......@@ -2,22 +2,7 @@
#define EXECUTE_H
#include "decode.h"
#define NREGS 17
#define PC 15
#define STACK_SIZE 16384
typedef struct decoded_data_processing {
type type;
unsigned int rn, rd, operand2, s_bit;
unsigned int carry_out, val_reg_last12bits;