<commit_before>// Copyright 2013 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "machine.h"

// Type of a machine word
typedef uint32_t mword;

// Used for converting between signed
// and unsigned machine words
typedef union {
    mword unsign;
    int32_t sign;
} signConverter;

#define MAX_MWORD 0xFFFFFFFF

state loadMachine(unsigned char *bin, mword len);
state runner();
void  cleanup();

// Used to extract bit fields
typedef union {
    mword word;
    
    // Bit fields for normal instruction word
    struct {
        unsigned int c:4;
        unsigned int b:4;
        unsigned int a:4;
        unsigned int junk:16;
        unsigned int op:4;
    } fields;
    
    // Bit fields for load value instruction word
    struct {
        unsigned int val:24;
        unsigned int a:4;
        unsigned int op:4;
    } loadValueFields;
} instruction;

// Type of functions which handle instructions
typedef state(cmd)(instruction);

cmd runCmd;

// The name "div" conflicts with a stdlib function
// so the naming convention must be broken with "divide" and "sdivide"
cmd move, eq, gt, sgt, lt, slt, cjmp, load, store, add, sadd, sub, ssub, mult, smult, divide, sdivide, and, or, xor, not, hlt, out, in, lval;

// Enumeration of instruction op codes
typedef enum {
    MOVE,   // Move
    EQ,     // Equality
    GT,     // Greater Than
    SGT,    // Signed Greater Than
    LT,     // Less Than
    SLT,    // Signed Less Than
    CJMP,   // Conditional Jump
    LOAD,   // Load
    STORE,  // Store
    ADD,    // Add
    SADD,   // Signed Add
    SUB,    // Subtract
    SSUB,   // Signed Subtract
    MULT,   // Multiply
    SMULT,  // Signed Multiply
    DIVIDE, // Divide
    SDIV,   // Signed Multiply
    AND,    // Bitwise And
    OR,     // Bitwise Or
    XOR,    // Bitwise Exclusive Or
    NOT,    // Bitwise Complement
    HLT,    // Halt
    OUT,    // Output
    IN,     // Input
    LVAL    // Load Value
} INSTR;

// Registers
mword reg[16];

// Program counter
mword ctr = 0;

// Memory
mword *memory = NULL;
mword memory_size = 0;

state runMachine(unsigned char *bin, uint32_t len) {
    state ret = loadMachine(bin, len);
    if (ret != RUN) {
        cleanup();
        return ret;
    }
    ret = runner();
    cleanup();
    return ret;
}

// Return relevant error, or RUN upon success
state loadMachine(unsigned char *bin, mword len) {
    
    memory_size = bin[0];
    memory_size <<= 8;
    memory_size |= bin[1];
    memory_size <<= 8;
    memory_size |= bin[2];
    memory_size <<= 8;
    memory_size |= bin[3];
    
    if ((memory_size * 4) < (len - 1))
        return FAIL;
    
    // Use calloc so memory is zero'd
    memory = (mword*)calloc(memory_size, sizeof(*memory));
    
    if (memory == NULL)
        return MEM;
    
    memcpy(memory, bin + sizeof(*memory), len);
    
    // Zero out registers
    memset(reg, 0, sizeof(*reg) * 16);
    ctr = 0;
    
    return RUN;
}

void cleanup() {
    if (memory != NULL)
        free(memory);
}

state runner() {
    while (1) {
        if (ctr >= memory_size)
            return FAIL;
        
        instruction instr;
        instr.word = memory[ctr];
        
        // Increment counter before running instruction
        // in case the instruction is a load program
        ctr++;
        state st = runCmd(instr);
        if (st != RUN)<commit_msg>Fixed bug where memcpy was copying bytes in the wrong order. Set bitfield lengths to the right values.<commit_after>// Copyright 2013 The Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "machine.h"

// Type of a machine word
typedef uint32_t mword;

// Used for converting between signed
// and unsigned machine words
typedef union {
    mword unsign;
    int32_t sign;
} signConverter;

#define MAX_MWORD 0xFFFFFFFF

state loadMachine(unsigned char *bin, mword len);
state runner();
void  cleanup();

// Used to extract bit fields
typedef union {
    mword word;
    
    // Bit fields for normal instruction word
    struct {
        unsigned int c:4;
        unsigned int b:4;
        unsigned int a:4;
        unsigned int junk:15;
        unsigned int op:5;
    } fields;
    
    // Bit fields for load value instruction word
    struct {
        unsigned int val:23;
        unsigned int a:4;
        unsigned int op:5;
    } loadValueFields;
} instruction;

// Type of functions which handle instructions
typedef state(cmd)(instruction);

cmd runCmd;

// The name "div" conflicts with a stdlib function
// so the naming convention must be broken with "divide" and "sdivide"
cmd move, eq, gt, sgt, lt, slt, cjmp, load, store, add, sadd, sub, ssub, mult, smult, divide, sdivide, and, or, xor, not, hlt, out, in, lval;

// Enumeration of instruction op codes
typedef enum {
    MOVE,   // Move
    EQ,     // Equality
    GT,     // Greater Than
    SGT,    // Signed Greater Than
    LT,     // Less Than
    SLT,    // Signed Less Than
    CJMP,   // Conditional Jump
    LOAD,   // Load
    STORE,  // Store
    ADD,    // Add
    SADD,   // Signed Add
    SUB,    // Subtract
    SSUB,   // Signed Subtract
    MULT,   // Multiply
    SMULT,  // Signed Multiply
    DIVIDE, // Divide
    SDIV,   // Signed Multiply
    AND,    // Bitwise And
    OR,     // Bitwise Or
    XOR,    // Bitwise Exclusive Or
    NOT,    // Bitwise Complement
    HLT,    // Halt
    OUT,    // Output
    IN,     // Input
    LVAL    // Load Value
} INSTR;

// Registers
mword reg[16];

// Program counter
mword ctr = 0;

// Memory
mword *memory = NULL;
mword memory_size = 0;

state runMachine(unsigned char *bin, uint32_t len) {
    state ret = loadMachine(bin, len);
    if (ret != RUN) {
        cleanup();
        return ret;
    }
    ret = runner();
    cleanup();
    return ret;
}

// Return relevant error, or RUN upon success
state loadMachine(unsigned char *bin, mword len) {
    
    memory_size = bin[0];
    memory_size <<= 8;
    memory_size |= bin[1];
    memory_size <<= 8;
    memory_size |= bin[2];
    memory_size <<= 8;
    memory_size |= bin[3];
    
    if ((memory_size * 4) < (len - 4))
        return FAIL;
    
    // Use calloc so memory is zero'd
    memory = (mword*)calloc(memory_size, sizeof(*memory));
    
    if (memory == NULL)
        return MEM;
    
    unsigned char *b = bin + 4;
    mword newWord;
    for (int i = 0; b < bin + len; i++) {
        newWord = *b;
        b++;
        newWord <<= 8;
        newWord |= *b;
        b++;
        newWord <<= 8;
        newWord |= *b;
        b++;
        newWord <<= 8;
        newWord |= *b;
        b++;
        memory[i] = newWord;
    }
    
    // Zero out registers
    memset(reg, 0, sizeof(*reg) * 16);
    ctr = 0;
    
    return RUN;
}

void cleanup() {
    if (memory != NULL)
        free(memory);
}

state runner() {
    while (1) {
        if (ctr >= memory_size)
            return FAIL;
        
        instruction instr;
        instr.word = memory[ctr];
        
        // Increment counter before running instruction
        // in case the instruction is a load program
        ctr++;
        state st = runCmd(instr);
        if (st != RUN)
{'fraction_non_alphanumeric': 0.11240154852489655, 'fraction_numerical': 0.011079962621812841, 'mean_word_length': 2.034426893479141, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7333552', 'n_tokens_mistral': 2517, 'n_tokens_neox': 2382, 'n_words': 837}