Beispiel #1
0
static void BasicBlock_WriteByteCode(KonohaContext *kctx, bblock_t blockId, ByteCodeWriter *writer)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL && bb->codeoffset == -1) {
		intptr_t len = bb->size - sizeof(BasicBlock);
		bb->codeoffset = CodeOffset(writer);
		bb->lastoffset = -1; // reset lastoffset
		if(len > 0) {
			bblock_t id = BasicBlock_id(kctx, bb);
			WriteByteCode(writer, ((char *)bb) + sizeof(BasicBlock), len);
			bb = BasicBlock_FindById(kctx, id);  // recheck
			bb->lastoffset = CodeOffset(writer) - sizeof(KVirtualCode);
			DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == (size_t) bb->lastoffset);
		}
		else {
			DBG_ASSERT(bb->branchid == -1);
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL) {
		if(bb->branchid != -1) {
			BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(bbJ->codeoffset == -1) {
				BasicBlock_WriteByteCode(kctx, bb->branchid, writer);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Beispiel #2
0
static BasicBlock *new_BasicBlock(KonohaContext *kctx, size_t max, bblock_t oldId)
{
	BasicBlock *bb;
	KBuffer wb;
	KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
	bb = (BasicBlock *)KLIB KBuffer_Alloca(kctx, &wb, max);
	if(oldId != -1) {
		BasicBlock *oldbb = BasicBlock_FindById(kctx, oldId);
		if(((char *)oldbb) + oldbb->max == (char *)bb) {
			oldbb->max += (max - sizeof(BasicBlock));
			wb.m->bytesize -= sizeof(BasicBlock);
			return oldbb;
		}
		memcpy(bb, oldbb, oldbb->size);
		oldbb->newid = BasicBlock_id(kctx, bb);
		oldbb->size = 0;
	}
	else {
		bb->size = sizeof(BasicBlock);
		bb->newid    = -1;
		bb->nextid   = -1;
		bb->branchid = -1;
	}
	bb->max = max;
	bb->codeoffset   = -1;
	bb->lastoffset   = -1;
	return bb;
}
Beispiel #3
0
static void BasicBlock_WriteBuffer(KonohaContext *kctx, bblock_t blockId, KBuffer *wb)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL && bb->codeoffset == -1) {
		size_t len = bb->size - sizeof(BasicBlock);
		bb->codeoffset = CodeOffset(wb);
		if(bb->nextid == bb->branchid  && bb->nextid != -1) {
			bb->branchid = -1;
			len -= sizeof(KVirtualCode); // remove unnecesarry jump ..
		}
		if(len > 0) {
			bblock_t id = BasicBlock_id(kctx, bb);
			char buf[len];  // bb is growing together with wb.
			memcpy(buf, ((char *)bb) + sizeof(BasicBlock), len);
			KLIB KBuffer_Write(kctx, wb, buf, len);
			bb = BasicBlock_FindById(kctx, id);  // recheck
			bb->lastoffset = CodeOffset(wb) - sizeof(KVirtualCode);
			DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == bb->lastoffset);
		}
		else {
			DBG_ASSERT(bb->branchid == -1);
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL) {
		if(bb->branchid != -1 /*&& bb->branchid != builder->bbReturnId*/) {
			BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(bbJ->codeoffset == -1) {
				BasicBlock_WriteBuffer(kctx, bb->branchid, wb);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Beispiel #4
0
static void MiniVMBuilder_setBlock(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *labelNode;
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	labelNode = BasicBlock_FindById(kctx, labelId);
	labelNode->incoming += 1;
	builder->bbMainId = BasicBlock_id(kctx, labelNode);
}
Beispiel #5
0
static void ASM_LABEL(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	DBG_ASSERT(bb->nextid == -1);
	BasicBlock *labelNode = BasicBlock_FindById(kctx, labelId);
	labelNode->incoming += 1;
	builder->bbMainId = BasicBlock_id(kctx, labelNode);
	bb->nextid = builder->bbMainId;
}
Beispiel #6
0
static void MiniVMBuilder_JumpTo(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	//DBG_ASSERT(bb->nextid == -1);
	if(bb->branchid == -1) {
		BasicBlock *labelNode;
		ASM(JMP, NULL);
		labelNode = BasicBlock_FindById(kctx, labelId);
		bb = BasicBlock_FindById(kctx, builder->bbMainId);
		bb->branchid = BasicBlock_id(kctx, labelNode);
		labelNode->incoming += 1;
	}
}
Beispiel #7
0
static bblock_t BasicBlock_Add(KonohaContext *kctx, bblock_t blockId, kfileline_t uline, KVirtualCode *op, size_t size, size_t padding_size)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	DBG_ASSERT(bb->newid == -1);
	DBG_ASSERT(size <= padding_size);
	DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1);
	if(!(bb->size + size < bb->max)) {
		size_t newsize = newsize2(bb->max);
		bb = new_BasicBlock(kctx, newsize, blockId);
	}
	memcpy(((char *)bb) + bb->size, op, size);
	bb->size += padding_size;
	return BasicBlock_id(kctx, bb);
}
Beispiel #8
0
static bblock_t AsmJMPF(KonohaContext *kctx, KBuilder *builder, int localStack, bblock_t jumpId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1);
	bblock_t nextId = new_BasicBlockLABEL(kctx);
	ASM(JMPF, NULL, NC_(localStack));
	bb = BasicBlock_FindById(kctx, builder->bbMainId);
	BasicBlock *jumpBlock = BasicBlock_FindById(kctx, jumpId);
	BasicBlock *nextBlock = BasicBlock_FindById(kctx, nextId);
	bb->branchid = BasicBlock_id(kctx, jumpBlock);
	bb->nextid = nextId;
	nextBlock->incoming += 1;
	jumpBlock->incoming += 1;
	builder->bbMainId = nextId;
	return nextId;
}
Beispiel #9
0
static bblock_t new_BasicBlockLABEL(KonohaContext *kctx)
{
	BasicBlock *bb = new_BasicBlock(kctx, sizeof(KVirtualCode) * 2 + sizeof(BasicBlock), -1);
	return BasicBlock_id(kctx, bb);
}