<commit_before>/*
 * libcpu: function.cpp
 *
 * Create the master function and fill it with the helper
 * basic blocks
 */

#include <vector>

#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/DataLayout.h"

#include "libcpu.h"
#include "libcpu_llvm.h"
#include "frontend.h" // XXX for arch_flags_encode() / arch_flags_decode()

//////////////////////////////////////////////////////////////////////
// function
//////////////////////////////////////////////////////////////////////

static StructType *
get_struct_reg(cpu_t *cpu, const char* name) {
	std::vector<Type*>type_struct_reg_t_fields;

	uint32_t count, size;
	
	// GPRs
	count = cpu->info.register_count[CPU_REG_GPR];
	size  = cpu->info.register_size[CPU_REG_GPR];
	for (uint32_t n = 0; n < count; n++)
		type_struct_reg_t_fields.push_back(getIntegerType(size));

	// XRs
	count = cpu->info.register_count[CPU_REG_XR];
	size  = cpu->info.register_size[CPU_REG_XR];
	for (uint32_t n = 0; n < count; n++)
		type_struct_reg_t_fields.push_back(getIntegerType(size));

//	type_struct_reg_t_fields.push_back(getIntegerType(cpu->info.address_size)); /* PC */

	return getNamedStructType(type_struct_reg_t_fields, name, /*isPacked=*/true);
}

static StructType *
get_struct_fp_reg(cpu_t *cpu, const char* name) {
	std::vector<Type*>type_struct_fp_reg_t_fields;

	uint32_t count, size;

	count = cpu->info.register_count[CPU_REG_FPR];
	size  = cpu->info.register_size[CPU_REG_FPR];
	for (uint32_t n = 0; n < count; n++) {
		if (size == 80) {
			if ((cpu->flags & CPU_FLAG_FP80) == 0) {
				/* two 64bits words hold the data */
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
			} else {
				// XXX ensure it is aligned to 16byte boundary!
				type_struct_fp_reg_t_fields.push_back(getFloatType(80));
			}
		} else if (size == 128) {
			if ((cpu->flags & CPU_FLAG_FP128) == 0) {
				/* two 64bits words hold the data */
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
			} else {
				type_struct_fp_reg_t_fields.push_back(getFloatType(128));
			}
		} else {
			type_struct_fp_reg_t_fields.push_back(getFloatType(size));
		}
	}

	return getNamedStructType(type_struct_fp_reg_t_fields, name, /*isPacked=*/true);
}

static Value *
get_struct_member_pointer(Value *s, int index, BasicBlock *bb) {
	ConstantInt* const_0 = ConstantInt::get(XgetType(Int32Ty), 0);
	ConstantInt* const_index = ConstantInt::get(XgetType(Int32Ty), index);

	SmallVector<Value*, 2> ptr_11_indices;
	ptr_11_indices.push_back(const_0);
	ptr_11_indices.push_back(const_index);
	return (Value*) GetElementPtrInst::Create(s, ptr_11_indices.begin(), ptr_11_indices.end(), "", bb);
}

static void
emit_decode_reg_helper(cpu_t *cpu, uint32_t count, uint32_t width,
	uint32_t offset, Value *rf, Value **in_ptr_r, Value **ptr_r,
	char const *rcname, BasicBlock *bb)
{
#ifdef OPT_LOCAL_REGISTERS
	// decode struct reg and copy the registers into local variables
	for (uint32_t i = 0; i < count; i++) {
		char reg_name[16];
		snprintf(reg_name, sizeof(reg_name), "%s_%u", rcname, i);

		in_ptr_r[i] = get_struct_member_pointer(rf, i + offset, bb);
		ptr_r[i] = new AllocaInst(getIntegerType(width), reg_name, bb);
		LoadInst* v = new LoadInst(in_ptr_r[i], "", false, bb);
		new StoreInst(v, ptr_r[i], false, bb);
	}
#else
	// just decode struct reg
	for (uint32_t i = 0; i < count; i++) <commit_msg>Fix GetElementPtrInstr::Create LLVM API call<commit_after>/*
 * libcpu: function.cpp
 *
 * Create the master function and fill it with the helper
 * basic blocks
 */

#include <vector>

#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/DataLayout.h"

#include "libcpu.h"
#include "libcpu_llvm.h"
#include "frontend.h" // XXX for arch_flags_encode() / arch_flags_decode()

//////////////////////////////////////////////////////////////////////
// function
//////////////////////////////////////////////////////////////////////

static StructType *
get_struct_reg(cpu_t *cpu, const char* name) {
	std::vector<Type*>type_struct_reg_t_fields;

	uint32_t count, size;
	
	// GPRs
	count = cpu->info.register_count[CPU_REG_GPR];
	size  = cpu->info.register_size[CPU_REG_GPR];
	for (uint32_t n = 0; n < count; n++)
		type_struct_reg_t_fields.push_back(getIntegerType(size));

	// XRs
	count = cpu->info.register_count[CPU_REG_XR];
	size  = cpu->info.register_size[CPU_REG_XR];
	for (uint32_t n = 0; n < count; n++)
		type_struct_reg_t_fields.push_back(getIntegerType(size));

//	type_struct_reg_t_fields.push_back(getIntegerType(cpu->info.address_size)); /* PC */

	return getNamedStructType(type_struct_reg_t_fields, name, /*isPacked=*/true);
}

static StructType *
get_struct_fp_reg(cpu_t *cpu, const char* name) {
	std::vector<Type*>type_struct_fp_reg_t_fields;

	uint32_t count, size;

	count = cpu->info.register_count[CPU_REG_FPR];
	size  = cpu->info.register_size[CPU_REG_FPR];
	for (uint32_t n = 0; n < count; n++) {
		if (size == 80) {
			if ((cpu->flags & CPU_FLAG_FP80) == 0) {
				/* two 64bits words hold the data */
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
			} else {
				// XXX ensure it is aligned to 16byte boundary!
				type_struct_fp_reg_t_fields.push_back(getFloatType(80));
			}
		} else if (size == 128) {
			if ((cpu->flags & CPU_FLAG_FP128) == 0) {
				/* two 64bits words hold the data */
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
				type_struct_fp_reg_t_fields.push_back(getIntegerType(64));
			} else {
				type_struct_fp_reg_t_fields.push_back(getFloatType(128));
			}
		} else {
			type_struct_fp_reg_t_fields.push_back(getFloatType(size));
		}
	}

	return getNamedStructType(type_struct_fp_reg_t_fields, name, /*isPacked=*/true);
}

static Value *
get_struct_member_pointer(Value *s, int index, BasicBlock *bb) {
	ConstantInt* const_0 = ConstantInt::get(XgetType(Int32Ty), 0);
	ConstantInt* const_index = ConstantInt::get(XgetType(Int32Ty), index);

	std::vector<Value*> ptr_11_indices;
	ptr_11_indices.push_back(const_0);
	ptr_11_indices.push_back(const_index);
	return (Value*) GetElementPtrInst::Create(s, ptr_11_indices, "", bb);
}

static void
emit_decode_reg_helper(cpu_t *cpu, uint32_t count, uint32_t width,
	uint32_t offset, Value *rf, Value **in_ptr_r, Value **ptr_r,
	char const *rcname, BasicBlock *bb)
{
#ifdef OPT_LOCAL_REGISTERS
	// decode struct reg and copy the registers into local variables
	for (uint32_t i = 0; i < count; i++) {
		char reg_name[16];
		snprintf(reg_name, sizeof(reg_name), "%s_%u", rcname, i);

		in_ptr_r[i] = get_struct_member_pointer(rf, i + offset, bb);
		ptr_r[i] = new AllocaInst(getIntegerType(width), reg_name, bb);
		LoadInst* v = new LoadInst(in_ptr_r[i], "", false, bb);
		new StoreInst(v, ptr_r[i], false, bb);
	}
#else
	// just decode struct reg
	for (uint32_t i = 0; i < count; i++) 
{'fraction_non_alphanumeric': 0.17040731504571904, 'fraction_numerical': 0.020642837351066777, 'mean_word_length': 4.145402708481825, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, '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': '1261618', 'n_tokens_mistral': 2882, 'n_tokens_neox': 2656, 'n_words': 524}