//===- RISCDisassemblerEmitter.cpp - Disassembler Generator ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// FIXME: document
//
//===----------------------------------------------------------------------===//
#include "RISCDisassemblerEmitter.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include <iostream>
#include <iomanip>
#include <vector>
#include <cstdio>
#include <map>
#include <string>
#include <sstream>
#include <asl.h>
using namespace llvm;
#pragma mark Utility classes / structures
// LLVM coding style
#define INDENT_LEVEL 2
class Indenter {
public:
Indenter() : fDepth(0) {
memset(fString, ' ', sizeof(fString));
fString[fDepth] = '\0';
}
void push() {
if (fDepth < sizeof(fString) - INDENT_LEVEL) {
fString[fDepth] = ' ';
fDepth += INDENT_LEVEL;
fString[fDepth] = '\0';
}
}
void pop() {
if(fDepth >= INDENT_LEVEL) {
fString[fDepth] = ' ';
fDepth -= INDENT_LEVEL;
fString[fDepth] = '\0';
}
}
const char* indent() const {
return &fString[0];
}
private:
char fString[256];
uint8_t fDepth;
};
#pragma mark Utility functions
#if 0
static int dprintf(int level, const char* format, ...) throw() {
static aslmsg* fMessage = NULL;
if (!fMessage) {
fMessage = new aslmsg;
*fMessage = asl_new(ASL_TYPE_MSG);
asl_set(*fMessage, ASL_KEY_FACILITY, "com.apple.llvm.disassembler.emitter.risc");
}
va_list ap;
va_start(ap, format);
int ret = asl_vlog(NULL, *fMessage, level, format, ap);
va_end(ap);
return ret;
}
#endif
static uint8_t byteFromBitsInit(BitsInit& init) {
int width = init.getNumBits();
assert(width <= 8 && "Field is too large for uint8_t!");
int index;
uint8_t mask = 0x01;
uint8_t ret = 0;
for (index = 0; index < width; index++) {
if (static_cast<BitInit*>(init.getBit(index))->getValue())
ret |= mask;
mask <<= 1;
}
return ret;
}
static uint8_t getByteField(const Record& def, const char* str) {
BitsInit* bits = def.getValueAsBitsInit(str);
return byteFromBitsInit(*bits);
}
static BitsInit& getBitsField(const Record& def, const char* str) {
BitsInit* bits = def.getValueAsBitsInit(str);
return *bits;
}
#if 0
static void binaryFromNumber(std::string& binary,
uint64_t number,
unsigned minimumWidth = 1) {
unsigned bitIndex;
bool emitting = false;
binary = "0b";
for (bitIndex = (sizeof(number) * 8); bitIndex > 0; bitIndex--) {
uint64_t bit = (number & (1 << (bitIndex - 1))) >> (bitIndex - 1);
if (bitIndex == minimumWidth)
emitting = true;
if (bit) {
emitting = true;
binary.append("1");
} else if(emitting) {
binary.append("0");
}
}
}
#endif
// The set (BIT_TRUE, BIT_FALSE, BIT_UNSET) represents a ternary logic system
// for a bit value.
//
// BIT_UNFILTERED is used as the init value for a filter position. It is used
// only for filter processings.
typedef enum {
BIT_TRUE, // '1'
BIT_FALSE