lot of instructions
This commit is contained in:
@@ -68,7 +68,6 @@ impl CPU {
|
|||||||
// fetch
|
// fetch
|
||||||
let inst = self.fetch();
|
let inst = self.fetch();
|
||||||
println!("VM > Fetched 0x{:08x}: 0x{:08x}", self.state.pc, inst);
|
println!("VM > Fetched 0x{:08x}: 0x{:08x}", self.state.pc, inst);
|
||||||
self.state.pc = self.state.pc + rv32::WORD as u32;
|
|
||||||
self.state.x[0] = 0x00000000;
|
self.state.x[0] = 0x00000000;
|
||||||
|
|
||||||
self.instruction_decoder
|
self.instruction_decoder
|
||||||
@@ -76,17 +75,19 @@ impl CPU {
|
|||||||
.decode_exec_inst(inst, &mut self.state)?;
|
.decode_exec_inst(inst, &mut self.state)?;
|
||||||
|
|
||||||
self.dump_reg();
|
self.dump_reg();
|
||||||
|
self.state.pc = self.state.pc + rv32::WORD as u32;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_reg(&mut self) {
|
fn dump_reg(&mut self) {
|
||||||
println!("VM > Dumping registers");
|
println!("VM > Dumping registers");
|
||||||
println!("PC : 0x{:08x}", self.state.pc);
|
println!(" > PC : 0x{:08x}", self.state.pc);
|
||||||
for i in 0..4 {
|
for i in 0..8 {
|
||||||
for j in 0..8 {
|
print!(" > ");
|
||||||
let coord = (i * 8) + j;
|
for j in 0..4 {
|
||||||
print!("x{0: <2}: {1: <4}", coord, self.state.x[coord]);
|
let coord = (i * 4) + j;
|
||||||
|
print!("x{0: <2}: 0x{1: <08x} ", coord, self.state.x[coord]);
|
||||||
}
|
}
|
||||||
println!("");
|
println!("");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ impl DecodeCycle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: speed this up by matching based on the opcode field and then fn3
|
// TODO: speed this up by matching based on the opcode field and then fn3
|
||||||
|
// TODO: Pass around only the union
|
||||||
pub fn decode_exec_inst(
|
pub fn decode_exec_inst(
|
||||||
&self,
|
&self,
|
||||||
inst: rv32::Word,
|
inst: rv32::Word,
|
||||||
|
|||||||
@@ -60,12 +60,12 @@ impl ImmediateMode for IType {
|
|||||||
|
|
||||||
#[bitfield]
|
#[bitfield]
|
||||||
pub struct SType {
|
pub struct SType {
|
||||||
opcode: B7,
|
pub opcode: B7,
|
||||||
imm_4_0: B5,
|
pub imm_4_0: B5,
|
||||||
funct3: B3,
|
pub funct3: B3,
|
||||||
rs1: B5,
|
pub rs1: B5,
|
||||||
rs2: B5,
|
pub rs2: B5,
|
||||||
imm_11_5: B7,
|
pub imm_11_5: B7,
|
||||||
}
|
}
|
||||||
|
|
||||||
// imm[11:5] = inst[31:25], imm[4:0] = inst[11:7]
|
// imm[11:5] = inst[31:25], imm[4:0] = inst[11:7]
|
||||||
@@ -81,33 +81,72 @@ impl ImmediateMode for SType {
|
|||||||
|
|
||||||
#[bitfield]
|
#[bitfield]
|
||||||
pub struct BType {
|
pub struct BType {
|
||||||
opcode: B7,
|
pub opcode: B7,
|
||||||
imm_11: B1,
|
pub imm_11: B1,
|
||||||
imm_4_1: B4,
|
pub imm_4_1: B4,
|
||||||
funct3: B3,
|
pub funct3: B3,
|
||||||
rs1: B5,
|
pub rs1: B5,
|
||||||
rs2: B5,
|
pub rs2: B5,
|
||||||
imm_10_5: B6,
|
pub imm_10_5: B6,
|
||||||
imm_12: B1,
|
pub imm_12: B1,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImmediateMode for BType {
|
||||||
|
fn sext_imm(&self) -> rv32::XLen {
|
||||||
|
helpers::sext(self.full_imm(), 12)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_imm(&self) -> rv32::XLen {
|
||||||
|
// >0b1 << 1 | 0b1 << 6 | 0b111110 << 4 | 0b1110
|
||||||
|
let imm_12 = self.imm_12() as rv32::XLen;
|
||||||
|
let imm_11 = self.imm_11() as rv32::XLen;
|
||||||
|
let imm_10_5 = self.imm_10_5() as rv32::XLen;
|
||||||
|
let imm_4_1 = self.imm_4_1() as rv32::XLen;
|
||||||
|
(imm_12 << 1) | (imm_11 << 1) | (imm_10_5 << 6) | imm_4_1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitfield]
|
#[bitfield]
|
||||||
pub struct UType {
|
pub struct UType {
|
||||||
opcode: B7,
|
pub opcode: B7,
|
||||||
rd: B5,
|
pub rd: B5,
|
||||||
imm: B20,
|
pub imm: B20,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImmediateMode for UType {
|
||||||
|
fn sext_imm(&self) -> rv32::XLen {
|
||||||
|
helpers::sext(self.full_imm(), 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_imm(&self) -> rv32::XLen {
|
||||||
|
self.imm()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bitfield]
|
#[bitfield]
|
||||||
pub struct JType {
|
pub struct JType {
|
||||||
opcode: B7,
|
pub opcode: B7,
|
||||||
rd: B5,
|
pub rd: B5,
|
||||||
imm_19_12: B8,
|
pub imm_19_12: B8,
|
||||||
imm_11: B1,
|
pub imm_11: B1,
|
||||||
imm_10_1: B10,
|
pub imm_10_1: B10,
|
||||||
imm_20: B1,
|
pub imm_20: B1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ImmediateMode for JType {
|
||||||
|
fn sext_imm(&self) -> rv32::XLen {
|
||||||
|
helpers::sext(self.full_imm(), 20)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_imm(&self) -> rv32::XLen {
|
||||||
|
// >0b1 << 1 | 0b1 << 6 | 0b111110 << 4 | 0b1110
|
||||||
|
let imm_20 = self.imm_20() as rv32::XLen;
|
||||||
|
let imm_19_12 = self.imm_19_12() as rv32::XLen;
|
||||||
|
let imm_11 = self.imm_11() as rv32::XLen;
|
||||||
|
let imm_10_1 = self.imm_10_1() as rv32::XLen;
|
||||||
|
(imm_20 << 8) | (imm_19_12 << 1) | (imm_11 << 10) | imm_10_1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(align(8))]
|
#[repr(align(8))]
|
||||||
pub union GenInstruction {
|
pub union GenInstruction {
|
||||||
|
|||||||
103
src/ext/i/mod.rs
103
src/ext/i/mod.rs
@@ -1,3 +1,5 @@
|
|||||||
|
use std::usize;
|
||||||
|
|
||||||
use bits::match_mask;
|
use bits::match_mask;
|
||||||
use enum_dispatch::*;
|
use enum_dispatch::*;
|
||||||
use strum::EnumIter;
|
use strum::EnumIter;
|
||||||
@@ -8,6 +10,95 @@ use crate::ext::encoding::ImmediateMode;
|
|||||||
use crate::helpers::sext;
|
use crate::helpers::sext;
|
||||||
use crate::system::rv32;
|
use crate::system::rv32;
|
||||||
|
|
||||||
|
// FOR BRANCH INSTRUCTIONS ITS IMPERATIVE TO REMEMBER
|
||||||
|
// THAT WE INCREMENT PC AFTER THE EXECUTION
|
||||||
|
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct LUI; // Load Upper Immediate
|
||||||
|
// Load the immedate mode value into the MSB of rd
|
||||||
|
// The last 12 bits of rd should be 0
|
||||||
|
impl Instruction for LUI {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"LUI"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
|
match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx0110111")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
||||||
|
println!("VM > Executing LUI");
|
||||||
|
let inst = unsafe { inst.U };
|
||||||
|
let val = inst.full_imm() << 12;
|
||||||
|
state.x[inst.rd() as usize] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct AUIPC; // Add Upper Immedate to PC
|
||||||
|
// Set rd to the immediate mode value + pc
|
||||||
|
impl Instruction for AUIPC {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"AUIPC"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
|
match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx0010111")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
||||||
|
println!("VM > Executing AUIPC");
|
||||||
|
let inst = unsafe { inst.U };
|
||||||
|
let val = inst.full_imm() << 12;
|
||||||
|
let pc_add = state.pc.wrapping_add(val);
|
||||||
|
state.x[inst.rd() as usize] = pc_add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct JAL; // Jump and Link
|
||||||
|
// Set pc to offset (imm) + pc
|
||||||
|
// Set rd to the old pc + 4
|
||||||
|
impl Instruction for JAL {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"JAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
|
match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx1101111")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
||||||
|
println!("VM > Executing JAL");
|
||||||
|
let inst = unsafe { inst.J };
|
||||||
|
let offset = sext(inst.full_imm() << 1, 32);
|
||||||
|
let pc = offset.wrapping_add(state.pc);
|
||||||
|
state.x[inst.rd() as usize] = state.pc + rv32::WORD as u32;
|
||||||
|
state.pc = pc - 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Copy, Clone)]
|
||||||
|
pub struct JALR; // JAL but R type offset encoding
|
||||||
|
// Add imm to rs1 then make it even (LSB = 0)
|
||||||
|
// Set the PC to the contents of rd
|
||||||
|
// Set rd to the old pc + 4
|
||||||
|
impl Instruction for JALR {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"JALR"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
|
match_mask!(inst, "xxxxxxxxxxxxxxxxxxxxxxxxx1101111")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
||||||
|
println!("VM > Executing JALR");
|
||||||
|
let inst = unsafe { inst.I };
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
#[derive(Default, Copy, Clone)]
|
||||||
pub struct ADDI;
|
pub struct ADDI;
|
||||||
|
|
||||||
@@ -17,17 +108,13 @@ impl Instruction for ADDI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn match_inst(&self, inst: rv32::Word) -> bool {
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
println!("VM > Checking ADDI");
|
|
||||||
println!("VM > ADDI: 0b{:032b}", inst);
|
|
||||||
println!("VM > ADDI: 0bxxxxxxxxxxxxxxxxx000xxxxx0010011");
|
|
||||||
match_mask!(inst, "xxxxxxxxxxxxxxxxx000xxxxx0010011")
|
match_mask!(inst, "xxxxxxxxxxxxxxxxx000xxxxx0010011")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
fn step(&self, inst: GenInstruction, state: &mut cpu::CPUState) {
|
||||||
println!("VM > Executing ADDI");
|
println!("VM > Executing ADDI");
|
||||||
let inst = unsafe { inst.I };
|
let inst = unsafe { inst.I };
|
||||||
state.x[inst.rd() as usize] =
|
state.x[inst.rd() as usize] = state.x[inst.rs1() as usize].wrapping_add(inst.sext_imm())
|
||||||
state.x[inst.rs1() as usize].wrapping_add(inst.sext_imm())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,9 +127,6 @@ impl Instruction for ADD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn match_inst(&self, inst: rv32::Word) -> bool {
|
fn match_inst(&self, inst: rv32::Word) -> bool {
|
||||||
println!("VM > Checking ADD");
|
|
||||||
println!("VM > ADD: 0b{:032b}", inst);
|
|
||||||
println!("VM > ADD: 0b0000000xxxxxxxxxx000xxxxx0110011");
|
|
||||||
match_mask!(inst, "0000000xxxxxxxxxx000xxxxx0110011")
|
match_mask!(inst, "0000000xxxxxxxxxx000xxxxx0110011")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +141,9 @@ impl Instruction for ADD {
|
|||||||
#[enum_dispatch(Instruction)]
|
#[enum_dispatch(Instruction)]
|
||||||
#[derive(EnumIter)]
|
#[derive(EnumIter)]
|
||||||
pub enum ExtensionI {
|
pub enum ExtensionI {
|
||||||
|
LUI(LUI),
|
||||||
|
AUIPC(AUIPC),
|
||||||
|
JAL(JAL),
|
||||||
ADDI(ADDI),
|
ADDI(ADDI),
|
||||||
ADD(ADD),
|
ADD(ADD),
|
||||||
}
|
}
|
||||||
|
|||||||
26
src/main.rs
26
src/main.rs
@@ -9,8 +9,8 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
mod cpu;
|
mod cpu;
|
||||||
mod err;
|
mod err;
|
||||||
mod ext;
|
mod ext;
|
||||||
mod system;
|
|
||||||
mod helpers;
|
mod helpers;
|
||||||
|
mod system;
|
||||||
|
|
||||||
use crate::cpu::*;
|
use crate::cpu::*;
|
||||||
use crate::ext::decode;
|
use crate::ext::decode;
|
||||||
@@ -27,8 +27,13 @@ impl VMRV32I {
|
|||||||
let extensions = vec!['i'];
|
let extensions = vec!['i'];
|
||||||
|
|
||||||
let bus = Rc::new(RefCell::new(bus::Bus::new()));
|
let bus = Rc::new(RefCell::new(bus::Bus::new()));
|
||||||
let instruction_decoder = Rc::new(RefCell::new(decode::DecodeCycle::new(extensions.clone())));
|
let instruction_decoder =
|
||||||
let mut cpu = CPU::new(Rc::clone(&bus), Rc::clone(&instruction_decoder), extensions.clone());
|
Rc::new(RefCell::new(decode::DecodeCycle::new(extensions.clone())));
|
||||||
|
let mut cpu = CPU::new(
|
||||||
|
Rc::clone(&bus),
|
||||||
|
Rc::clone(&instruction_decoder),
|
||||||
|
extensions.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
cpu.init();
|
cpu.init();
|
||||||
VMRV32I {
|
VMRV32I {
|
||||||
@@ -38,7 +43,7 @@ impl VMRV32I {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_prog(&mut self, file: &str) {
|
fn load_prog(&mut self, file: &str) -> u32 {
|
||||||
println!("VM > Loading program: {}", file);
|
println!("VM > Loading program: {}", file);
|
||||||
|
|
||||||
let f = File::open(file).expect("file not found");
|
let f = File::open(file).expect("file not found");
|
||||||
@@ -56,11 +61,12 @@ impl VMRV32I {
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("VM > Program loaded to 0x{:08x}", self.cpu.get_pc());
|
println!("VM > Program loaded to 0x{:08x}", self.cpu.get_pc());
|
||||||
|
buffer.len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump_prog(&mut self) {
|
fn dump_prog(&mut self, size: u32) {
|
||||||
println!("VM > Dumping program (virtual addresses)");
|
println!("VM > Dumping program (virtual addresses)");
|
||||||
for i in 0..12 {
|
for i in 0..size {
|
||||||
if i % 4 == 0 {
|
if i % 4 == 0 {
|
||||||
println!(
|
println!(
|
||||||
"VM > 0x{:08x}: 0x{:08x}",
|
"VM > 0x{:08x}: 0x{:08x}",
|
||||||
@@ -71,6 +77,10 @@ impl VMRV32I {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dump_relavent_memory(&self) {
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
|
||||||
fn dispatch(&mut self) {
|
fn dispatch(&mut self) {
|
||||||
match self.cpu.exec() {
|
match self.cpu.exec() {
|
||||||
Ok(_) => println!("VM > Program exited peacefully"),
|
Ok(_) => println!("VM > Program exited peacefully"),
|
||||||
@@ -83,7 +93,7 @@ fn main() {
|
|||||||
println!("VM Starting Up");
|
println!("VM Starting Up");
|
||||||
|
|
||||||
let mut vm = VMRV32I::new();
|
let mut vm = VMRV32I::new();
|
||||||
vm.load_prog("./test/test.bin");
|
let size = vm.load_prog("./test/test.bin");
|
||||||
vm.dump_prog();
|
vm.dump_prog(size);
|
||||||
vm.dispatch();
|
vm.dispatch();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ use crate::system::bus;
|
|||||||
use crate::system::rv32;
|
use crate::system::rv32;
|
||||||
|
|
||||||
//pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB
|
//pub const DRAM_SIZE: u32 = 1 * 1024 * 1024 * 1024; // 1GB
|
||||||
//pub const DRAM_SIZE: u32 = 1 * 1024; // 1KB
|
pub const DRAM_SIZE: u32 = 1 * 1024; // 1KB
|
||||||
pub const DRAM_SIZE: u32 = 12;
|
|
||||||
|
|
||||||
pub struct RAM(pub Vec<rv32::Byte>);
|
pub struct RAM(pub Vec<rv32::Byte>);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
GCC_COMPILER=riscv32-unknown-elf-gcc
|
TARGET=test
|
||||||
GCC_OBJCOPY=riscv32-unknown-elf-objcopy
|
GCC_PREFIX=riscv32-unknown-elf
|
||||||
|
|
||||||
all: bin
|
all: build
|
||||||
|
|
||||||
assemble:
|
assemble:
|
||||||
$(GCC_COMPILER) -S test.c
|
$(GCC_PREFIX)-gcc -S $(TARGET).c
|
||||||
|
|
||||||
build:
|
build:
|
||||||
$(GCC_COMPILER) -Wl,-Ttext=0x0 -nostdlib -march=rv64i -mabi=lp64 -o test test.S
|
$(GCC_PREFIX)-gcc -Wl,-Ttext=0x0 -nostdlib -march=rv64i -mabi=lp64 -o $(TARGET) $(TARGET).S
|
||||||
|
$(GCC_PREFIX)-objdump -t $(TARGET) > $(TARGET).map
|
||||||
bin: build
|
$(GCC_PREFIX)-objdump -S $(TARGET) > $(TARGET).lst
|
||||||
$(GCC_OBJCOPY) -O binary test test.bin
|
$(GCC_PREFIX)-objcopy -O binary $(TARGET) $(TARGET).bin
|
||||||
|
$(GCC_PREFIX)-objcopy -O ihex $(TARGET) $(TARGET).hex
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f test test.bin
|
rm -f $(TARGET) $(TARGET).bin
|
||||||
|
|
||||||
|
|||||||
236
test/binary_search.s
Normal file
236
test/binary_search.s
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
.file "binary_search.c"
|
||||||
|
.option nopic
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl binary_search
|
||||||
|
.type binary_search, @function
|
||||||
|
binary_search:
|
||||||
|
addi sp,sp,-48
|
||||||
|
sw ra,44(sp)
|
||||||
|
sw s0,40(sp)
|
||||||
|
addi s0,sp,48
|
||||||
|
sw a0,-36(s0)
|
||||||
|
sw a1,-40(s0)
|
||||||
|
sw a2,-44(s0)
|
||||||
|
sw a3,-48(s0)
|
||||||
|
lw a4,-48(s0)
|
||||||
|
lw a5,-44(s0)
|
||||||
|
sub a5,a4,a5
|
||||||
|
srli a4,a5,31
|
||||||
|
add a5,a4,a5
|
||||||
|
srai a5,a5,1
|
||||||
|
mv a4,a5
|
||||||
|
lw a5,-44(s0)
|
||||||
|
add a5,a5,a4
|
||||||
|
sw a5,-20(s0)
|
||||||
|
lw a4,-44(s0)
|
||||||
|
lw a5,-48(s0)
|
||||||
|
ble a4,a5,.L2
|
||||||
|
li a5,-1
|
||||||
|
j .L3
|
||||||
|
.L2:
|
||||||
|
lw a5,-20(s0)
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
lw a5,0(a5)
|
||||||
|
lw a4,-40(s0)
|
||||||
|
bne a4,a5,.L4
|
||||||
|
lw a5,-20(s0)
|
||||||
|
j .L3
|
||||||
|
.L4:
|
||||||
|
lw a5,-20(s0)
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
lw a5,0(a5)
|
||||||
|
lw a4,-40(s0)
|
||||||
|
bge a4,a5,.L5
|
||||||
|
lw a5,-20(s0)
|
||||||
|
addi a5,a5,-1
|
||||||
|
mv a3,a5
|
||||||
|
lw a2,-44(s0)
|
||||||
|
lw a1,-40(s0)
|
||||||
|
lw a0,-36(s0)
|
||||||
|
call binary_search
|
||||||
|
mv a5,a0
|
||||||
|
j .L3
|
||||||
|
.L5:
|
||||||
|
lw a5,-20(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
lw a3,-48(s0)
|
||||||
|
mv a2,a5
|
||||||
|
lw a1,-40(s0)
|
||||||
|
lw a0,-36(s0)
|
||||||
|
call binary_search
|
||||||
|
mv a5,a0
|
||||||
|
.L3:
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,44(sp)
|
||||||
|
lw s0,40(sp)
|
||||||
|
addi sp,sp,48
|
||||||
|
jr ra
|
||||||
|
.size binary_search, .-binary_search
|
||||||
|
.align 2
|
||||||
|
.globl search
|
||||||
|
.type search, @function
|
||||||
|
search:
|
||||||
|
addi sp,sp,-32
|
||||||
|
sw ra,28(sp)
|
||||||
|
sw s0,24(sp)
|
||||||
|
addi s0,sp,32
|
||||||
|
sw a0,-20(s0)
|
||||||
|
sw a1,-24(s0)
|
||||||
|
sw a2,-28(s0)
|
||||||
|
lw a5,-28(s0)
|
||||||
|
addi a5,a5,-1
|
||||||
|
mv a3,a5
|
||||||
|
li a2,0
|
||||||
|
lw a1,-24(s0)
|
||||||
|
lw a0,-20(s0)
|
||||||
|
call binary_search
|
||||||
|
mv a5,a0
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,28(sp)
|
||||||
|
lw s0,24(sp)
|
||||||
|
addi sp,sp,32
|
||||||
|
jr ra
|
||||||
|
.size search, .-search
|
||||||
|
.align 2
|
||||||
|
.globl sort
|
||||||
|
.type sort, @function
|
||||||
|
sort:
|
||||||
|
addi sp,sp,-48
|
||||||
|
sw s0,44(sp)
|
||||||
|
addi s0,sp,48
|
||||||
|
sw a0,-36(s0)
|
||||||
|
sw a1,-40(s0)
|
||||||
|
sw zero,-20(s0)
|
||||||
|
j .L9
|
||||||
|
.L13:
|
||||||
|
sw zero,-24(s0)
|
||||||
|
j .L10
|
||||||
|
.L12:
|
||||||
|
lw a5,-24(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
lw a4,0(a5)
|
||||||
|
lw a5,-24(s0)
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a3,-36(s0)
|
||||||
|
add a5,a3,a5
|
||||||
|
lw a5,0(a5)
|
||||||
|
bge a4,a5,.L11
|
||||||
|
lw a5,-24(s0)
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
lw a5,0(a5)
|
||||||
|
sw a5,-28(s0)
|
||||||
|
lw a5,-24(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a4,a4,a5
|
||||||
|
lw a5,-24(s0)
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a3,-36(s0)
|
||||||
|
add a5,a3,a5
|
||||||
|
lw a4,0(a4)
|
||||||
|
sw a4,0(a5)
|
||||||
|
lw a5,-24(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
slli a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
lw a4,-28(s0)
|
||||||
|
sw a4,0(a5)
|
||||||
|
.L11:
|
||||||
|
lw a5,-24(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
sw a5,-24(s0)
|
||||||
|
.L10:
|
||||||
|
lw a4,-40(s0)
|
||||||
|
lw a5,-20(s0)
|
||||||
|
sub a5,a4,a5
|
||||||
|
addi a5,a5,-1
|
||||||
|
lw a4,-24(s0)
|
||||||
|
blt a4,a5,.L12
|
||||||
|
lw a5,-20(s0)
|
||||||
|
addi a5,a5,1
|
||||||
|
sw a5,-20(s0)
|
||||||
|
.L9:
|
||||||
|
lw a5,-40(s0)
|
||||||
|
addi a5,a5,-1
|
||||||
|
lw a4,-20(s0)
|
||||||
|
blt a4,a5,.L13
|
||||||
|
nop
|
||||||
|
mv a0,a5
|
||||||
|
lw s0,44(sp)
|
||||||
|
addi sp,sp,48
|
||||||
|
jr ra
|
||||||
|
.size sort, .-sort
|
||||||
|
.section .rodata
|
||||||
|
.align 2
|
||||||
|
.LC0:
|
||||||
|
.word 0
|
||||||
|
.word 6
|
||||||
|
.word 8
|
||||||
|
.word 4
|
||||||
|
.word 3
|
||||||
|
.word 9
|
||||||
|
.word 7
|
||||||
|
.word 5
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
addi sp,sp,-64
|
||||||
|
sw ra,60(sp)
|
||||||
|
sw s0,56(sp)
|
||||||
|
addi s0,sp,64
|
||||||
|
lui a5,%hi(.LC0)
|
||||||
|
lw a7,%lo(.LC0)(a5)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a6,4(a4)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a0,8(a4)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a1,12(a4)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a2,16(a4)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a3,20(a4)
|
||||||
|
addi a4,a5,%lo(.LC0)
|
||||||
|
lw a4,24(a4)
|
||||||
|
addi a5,a5,%lo(.LC0)
|
||||||
|
lw a5,28(a5)
|
||||||
|
sw a7,-52(s0)
|
||||||
|
sw a6,-48(s0)
|
||||||
|
sw a0,-44(s0)
|
||||||
|
sw a1,-40(s0)
|
||||||
|
sw a2,-36(s0)
|
||||||
|
sw a3,-32(s0)
|
||||||
|
sw a4,-28(s0)
|
||||||
|
sw a5,-24(s0)
|
||||||
|
addi a5,s0,-52
|
||||||
|
li a1,8
|
||||||
|
mv a0,a5
|
||||||
|
call sort
|
||||||
|
addi a5,s0,-52
|
||||||
|
li a2,8
|
||||||
|
li a1,9
|
||||||
|
mv a0,a5
|
||||||
|
call search
|
||||||
|
sw a0,-20(s0)
|
||||||
|
lw a5,-20(s0)
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,60(sp)
|
||||||
|
lw s0,56(sp)
|
||||||
|
addi sp,sp,64
|
||||||
|
jr ra
|
||||||
|
.size main, .-main
|
||||||
|
.ident "GCC: (GNU) 7.2.0"
|
||||||
76
test/fibonacci.s
Normal file
76
test/fibonacci.s
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
.file "fibonacci.c"
|
||||||
|
.option nopic
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl fib
|
||||||
|
.type fib, @function
|
||||||
|
fib:
|
||||||
|
addi sp,sp,-32
|
||||||
|
sw ra,28(sp)
|
||||||
|
sw s0,24(sp)
|
||||||
|
sw s1,20(sp)
|
||||||
|
addi s0,sp,32
|
||||||
|
sw a0,-20(s0)
|
||||||
|
lw a4,-20(s0)
|
||||||
|
li a5,1
|
||||||
|
bgt a4,a5,.L2
|
||||||
|
lw a5,-20(s0)
|
||||||
|
j .L3
|
||||||
|
.L2:
|
||||||
|
lw a5,-20(s0)
|
||||||
|
addi a5,a5,-1
|
||||||
|
mv a0,a5
|
||||||
|
call fib
|
||||||
|
mv s1,a0
|
||||||
|
lw a5,-20(s0)
|
||||||
|
addi a5,a5,-2
|
||||||
|
mv a0,a5
|
||||||
|
call fib
|
||||||
|
mv a5,a0
|
||||||
|
add a5,s1,a5
|
||||||
|
.L3:
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,28(sp)
|
||||||
|
lw s0,24(sp)
|
||||||
|
lw s1,20(sp)
|
||||||
|
addi sp,sp,32
|
||||||
|
jr ra
|
||||||
|
.size fib, .-fib
|
||||||
|
.align 2
|
||||||
|
.globl return_function
|
||||||
|
.type return_function, @function
|
||||||
|
return_function:
|
||||||
|
addi sp,sp,-32
|
||||||
|
sw s0,28(sp)
|
||||||
|
addi s0,sp,32
|
||||||
|
sw a0,-20(s0)
|
||||||
|
lw a5,-20(s0)
|
||||||
|
mv a0,a5
|
||||||
|
lw s0,28(sp)
|
||||||
|
addi sp,sp,32
|
||||||
|
jr ra
|
||||||
|
.size return_function, .-return_function
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
addi sp,sp,-32
|
||||||
|
sw ra,28(sp)
|
||||||
|
sw s0,24(sp)
|
||||||
|
addi s0,sp,32
|
||||||
|
li a5,18
|
||||||
|
sw a5,-20(s0)
|
||||||
|
lw a0,-20(s0)
|
||||||
|
call fib
|
||||||
|
mv a5,a0
|
||||||
|
mv a0,a5
|
||||||
|
call return_function
|
||||||
|
sw a0,-24(s0)
|
||||||
|
lw a5,-24(s0)
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,28(sp)
|
||||||
|
lw s0,24(sp)
|
||||||
|
addi sp,sp,32
|
||||||
|
jr ra
|
||||||
|
.size main, .-main
|
||||||
|
.ident "GCC: (GNU) 7.2.0"
|
||||||
70
test/gcd.s
Normal file
70
test/gcd.s
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.file "gcd.c"
|
||||||
|
.option nopic
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl gcd
|
||||||
|
.type gcd, @function
|
||||||
|
gcd:
|
||||||
|
addi sp,sp,-48
|
||||||
|
sw ra,44(sp)
|
||||||
|
sw s0,40(sp)
|
||||||
|
addi s0,sp,48
|
||||||
|
sw a0,-36(s0)
|
||||||
|
sw a1,-40(s0)
|
||||||
|
lw a4,-36(s0)
|
||||||
|
lw a5,-40(s0)
|
||||||
|
bne a4,a5,.L2
|
||||||
|
lw a5,-36(s0)
|
||||||
|
sw a5,-20(s0)
|
||||||
|
j .L3
|
||||||
|
.L2:
|
||||||
|
lw a4,-36(s0)
|
||||||
|
lw a5,-40(s0)
|
||||||
|
ble a4,a5,.L4
|
||||||
|
lw a4,-36(s0)
|
||||||
|
lw a5,-40(s0)
|
||||||
|
sub a5,a4,a5
|
||||||
|
sw a5,-36(s0)
|
||||||
|
j .L5
|
||||||
|
.L4:
|
||||||
|
lw a4,-40(s0)
|
||||||
|
lw a5,-36(s0)
|
||||||
|
sub a5,a4,a5
|
||||||
|
sw a5,-40(s0)
|
||||||
|
.L5:
|
||||||
|
lw a1,-40(s0)
|
||||||
|
lw a0,-36(s0)
|
||||||
|
call gcd
|
||||||
|
sw a0,-20(s0)
|
||||||
|
.L3:
|
||||||
|
lw a5,-20(s0)
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,44(sp)
|
||||||
|
lw s0,40(sp)
|
||||||
|
addi sp,sp,48
|
||||||
|
jr ra
|
||||||
|
.size gcd, .-gcd
|
||||||
|
.align 2
|
||||||
|
.globl main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
addi sp,sp,-32
|
||||||
|
sw ra,28(sp)
|
||||||
|
sw s0,24(sp)
|
||||||
|
addi s0,sp,32
|
||||||
|
li a5,64
|
||||||
|
sw a5,-20(s0)
|
||||||
|
li a5,48
|
||||||
|
sw a5,-24(s0)
|
||||||
|
lw a1,-24(s0)
|
||||||
|
lw a0,-20(s0)
|
||||||
|
call gcd
|
||||||
|
sw a0,-28(s0)
|
||||||
|
lw a5,-28(s0)
|
||||||
|
mv a0,a5
|
||||||
|
lw ra,28(sp)
|
||||||
|
lw s0,24(sp)
|
||||||
|
addi sp,sp,32
|
||||||
|
jr ra
|
||||||
|
.size main, .-main
|
||||||
|
.ident "GCC: (GNU) 7.2.0"
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
jal x0, main
|
j main
|
||||||
|
lui x2, 0xFFFFF
|
||||||
|
addi t1, x0, 0x123
|
||||||
|
auipc x3, 0x12345
|
||||||
|
|
||||||
main:
|
main:
|
||||||
addi t0, x0, 100
|
addi t0, x0, 100
|
||||||
sb t0, 8(sp)
|
|
||||||
|
|||||||
BIN
test/test.bin
BIN
test/test.bin
Binary file not shown.
3
test/test.hex
Normal file
3
test/test.hex
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
:100000006F00000137F1FFFF1303301297513412D4
|
||||||
|
:040010009302400611
|
||||||
|
:00000001FF
|
||||||
14
test/test.lst
Normal file
14
test/test.lst
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
test: file format elf64-littleriscv
|
||||||
|
|
||||||
|
|
||||||
|
Disassembly of section .text:
|
||||||
|
|
||||||
|
0000000000000000 <main-0x10>:
|
||||||
|
0: 0100006f j 10 <main>
|
||||||
|
4: fffff137 lui sp,0xfffff
|
||||||
|
8: 12300313 li t1,291
|
||||||
|
c: 12345197 auipc gp,0x12345
|
||||||
|
|
||||||
|
0000000000000010 <main>:
|
||||||
|
10: 06400293 li t0,100
|
||||||
18
test/test.map
Normal file
18
test/test.map
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
test: file format elf64-littleriscv
|
||||||
|
|
||||||
|
SYMBOL TABLE:
|
||||||
|
0000000000000000 l d .text 0000000000000000 .text
|
||||||
|
0000000000000000 l d .riscv.attributes 0000000000000000 .riscv.attributes
|
||||||
|
0000000000000000 l df *ABS* 0000000000000000 ccC0QKeL.o
|
||||||
|
0000000000000010 l .text 0000000000000000 main
|
||||||
|
0000000000001814 g *ABS* 0000000000000000 __global_pointer$
|
||||||
|
0000000000001014 g .text 0000000000000000 __SDATA_BEGIN__
|
||||||
|
0000000000000000 *UND* 0000000000000000 _start
|
||||||
|
0000000000001018 g .text 0000000000000000 __BSS_END__
|
||||||
|
0000000000001014 g .text 0000000000000000 __bss_start
|
||||||
|
0000000000001014 g .text 0000000000000000 __DATA_BEGIN__
|
||||||
|
0000000000001014 g .text 0000000000000000 _edata
|
||||||
|
0000000000001018 g .text 0000000000000000 _end
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user