diff --git a/src/ch2/linkedlist.rs b/src/ch2/linkedlist.rs index de02c09..94e7ef6 100644 --- a/src/ch2/linkedlist.rs +++ b/src/ch2/linkedlist.rs @@ -1,6 +1,7 @@ pub mod tests { - use compiler::backend::{AddInst, Block, BranchInst, BranchOp, CallInst, Inst, JmpInst, MvInst, REG_A0, REG_A1, REG_A2, REG_RA, REG_S0, REG_S1, REG_S2, REG_SP, REG_ZERO, SdInst}; - use compiler::backend::Inst::Call; + use compiler::backend::{AddInst, Block, BranchInst, BranchOp, CallInst, Inst, JmpInst, LdInst, MvInst, REG_A0, REG_A1, REG_A2, REG_RA, REG_S0, REG_S1, REG_S2, REG_SP, REG_ZERO, SdInst}; + use compiler::backend::Inst::{Call, Jmp}; + use compiler::frontend::Decl::Func; #[test] pub fn linked() { @@ -10,19 +11,35 @@ pub mod tests { let lia08 = Inst::Add(AddInst::new(REG_A0.into(), REG_ZERO.into(), (-16).into())); let sdra8sp = Inst::Sd(SdInst::new(REG_RA.into(), (8).into(), REG_SP.into())); let sds00sp = Inst::Sd(SdInst::new(REG_S0.into(), (0).into(), REG_SP.into())); - let callmalloc = Inst::Call(CallInst::new("malloc@plt".into())); + let callmalloc1 = Inst::Call(CallInst::new("malloc@plt".into())); let beqa0zerol2 = Inst::Branch(BranchInst::new(BranchOp::Beq, REG_A0.into(), REG_ZERO.into(), "L2".into())); let mvs0a0 = Inst::Mv(MvInst::new(REG_S0.into(), REG_A0.into())); let lia016 = Inst::Add(AddInst::new(REG_A0.into(), REG_ZERO.into(), (16).into())); - let callmalloc = Inst::Call(CallInst::new("malloc@plt".into())); + let callmalloc2 = Inst::Call(CallInst::new("malloc@plt".into())); let sda00s0 = Inst::Sd(SdInst::new(REG_A0.into(), (0).into(), REG_S0.into())); let beqa0zerol3 = Inst::Branch(BranchInst::new(BranchOp::Beq, REG_A0.into(), REG_ZERO.into(), "L3".into())); + let sdzero8a0 = Inst::Sd(SdInst::new(REG_ZERO.into(), (8).into(), REG_A0.into())); + entry.extend_insts(vec![addispsp_16, lia08, sdra8sp, sds00sp, callmalloc1, beqa0zerol2, mvs0a0, lia016, callmalloc2, sda00s0, beqa0zerol3, sdzero8a0]); + // L1 + let mut l1 = Block::new("L1".into()); + let ldra8sp = Inst::Ld(LdInst::new(REG_RA.into(), (8).into(), REG_SP.into())); + let mva0s0 = Inst::Mv(MvInst::new(REG_A0.into(), REG_S0.into())); + let lds00sp = Inst::Ld(LdInst::new(REG_S0.into(), (0).into(), REG_SP.into())); + let addispsp16 = Inst::Add(AddInst::new(REG_SP.into(), REG_SP.into(), (8).into())); + let ret = Inst::Ret; + l1.extend_insts(vec![ldra8sp, mva0s0, lds00sp, addispsp16, ret]); + let mut l3 = Block::new("L3".into()); + let mva0s0 = Inst::Mv(MvInst::new(REG_A0.into(), REG_S0.into())); + let callfree = Inst::Call(CallInst::new("free@plt".into())); + l3.extend_insts(vec![mva0s0, callfree]); + let mut l2 = Block::new("l2".into()); + let lis00 = Inst::Add(AddInst::new(REG_S0.into(), REG_ZERO.into(), (0).into())); + let jl1 = Inst::Jmp(JmpInst::new("L1".into())); + l2.extend_insts(vec![lis00, jl1]); - - - - - - + let createLinkedList = Func::new("createLinkedList".into(), Vec::new(), entry); + createLinkedList.push_bb(l1); + createLinkedList.push_bb(l2); + createLinkedList.push_bb(l3); } } \ No newline at end of file diff --git a/src/ch2/list.c b/src/ch2/list.c new file mode 100644 index 0000000..05b296a --- /dev/null +++ b/src/ch2/list.c @@ -0,0 +1,78 @@ +#include +#include + +// 定义链表节点结构体 +typedef struct ListNode { + int data; // 数据域 + struct ListNode *next; // 指向下一个节点的指针 +} ListNode; + +// 定义链表结构体,这里我们的链表包含一个头结点 +typedef struct LinkedList { + ListNode *head; // 指向头结点的指针 +} LinkedList; + +// 创建链表,初始化头结点 +LinkedList *createLinkedList() { + LinkedList *list = (LinkedList *)malloc(sizeof(LinkedList)); + if (list) { + list->head = (ListNode *)malloc(sizeof(ListNode)); // 创建头结点 + if (list->head) { + list->head->next = NULL; // 头结点的next指向NULL + } else { + free(list); // 如果头结点创建失败,释放链表结构体所占内存 + return NULL; + } + } + return list; +} + +// 在链表尾部插入节点 +void insertNode(LinkedList *list, int data) { + ListNode *newNode = (ListNode *)malloc(sizeof(ListNode)); + newNode->data = data; + newNode->next = NULL; + + // 找到链表的最后一个节点 + ListNode *current = list->head; + while (current->next != NULL) { + current = current->next; + } + // 将新节点插入到链表尾部 + current->next = newNode; +} + +// 删除链表中的节点 +void deleteNode(LinkedList *list, int data) { + ListNode *current = list->head; + ListNode *previous = NULL; + while (current->next != NULL && current->next->data != data) { + previous = current; + current = current->next; + } + if (current->next != NULL) { + ListNode *temp = current->next; + current->next = current->next->next; + free(temp); + } +} + +// 查找链表中的节点 +ListNode *findNode(LinkedList *list, int data) { + ListNode *current = list->head->next; // 从第一个实际存储数据的节点开始 + while (current != NULL && current->data != data) { + current = current->next; + } + return current; +} + +// 销毁链表 +void destroyLinkedList(LinkedList *list) { + ListNode *current = list->head; + while (current != NULL) { + ListNode *temp = current; + current = current->next; + free(temp); + } + free(list); +} diff --git a/src/ch2/list.s b/src/ch2/list.s new file mode 100644 index 0000000..f25775f --- /dev/null +++ b/src/ch2/list.s @@ -0,0 +1,125 @@ + .file "list.c" + .option pic + .attribute arch, "rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0" + .attribute unaligned_access, 0 + .attribute stack_align, 16 + .text + .align 1 + .globl createLinkedList + .type createLinkedList, @function +createLinkedList: + addi sp,sp,-16 + li a0,8 + sd ra,8(sp) + sd s0,0(sp) + call malloc@plt + beq a0,zero,.L2 + mv s0,a0 + li a0,16 + call malloc@plt + sd a0,0(s0) + beq a0,zero,.L3 + sd zero,8(a0) +.L1: + ld ra,8(sp) + mv a0,s0 + ld s0,0(sp) + addi sp,sp,16 + jr ra +.L3: + mv a0,s0 + call free@plt +.L2: + li s0,0 + j .L1 + .size createLinkedList, .-createLinkedList + .align 1 + .globl insertNode + .type insertNode, @function +insertNode: + addi sp,sp,-32 + sd s1,8(sp) + mv s1,a0 + li a0,16 + sd s0,16(sp) + sd ra,24(sp) + mv s0,a1 + call malloc@plt + ld a5,0(s1) + sw s0,0(a0) + sd zero,8(a0) +.L11: + mv a4,a5 + ld a5,8(a5) + bne a5,zero,.L11 + ld ra,24(sp) + ld s0,16(sp) + sd a0,8(a4) + ld s1,8(sp) + addi sp,sp,32 + jr ra + .size insertNode, .-insertNode + .align 1 + .globl deleteNode + .type deleteNode, @function +deleteNode: + ld a0,0(a0) + j .L16 +.L20: + lw a5,0(a0) + beq a5,a1,.L19 +.L16: + mv a4,a0 + ld a0,8(a0) + bne a0,zero,.L20 + ret +.L19: + ld a5,8(a0) + sd a5,8(a4) + tail free@plt + .size deleteNode, .-deleteNode + .align 1 + .globl findNode + .type findNode, @function +findNode: + ld a5,0(a0) + ld a0,8(a5) + bne a0,zero,.L22 + j .L29 +.L24: + ld a0,8(a0) + beq a0,zero,.L21 +.L22: + lw a5,0(a0) + bne a5,a1,.L24 +.L21: + ret +.L29: + ret + .size findNode, .-findNode + .align 1 + .globl destroyLinkedList + .type destroyLinkedList, @function +destroyLinkedList: + addi sp,sp,-32 + sd s0,16(sp) + ld s0,0(a0) + sd s1,8(sp) + sd ra,24(sp) + mv s1,a0 + beq s0,zero,.L31 +.L32: + mv a0,s0 + ld s0,8(s0) + call free@plt + bne s0,zero,.L32 +.L31: + ld s0,16(sp) + ld ra,24(sp) + mv a0,s1 + ld s1,8(sp) + addi sp,sp,32 + tail free@plt + .size destroyLinkedList, .-destroyLinkedList + .ident "GCC: (Debian 12.2.0-13) 12.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/src/ch2/quicksort.rs b/src/ch2/quicksort.rs index cc140ba..a2ba862 100644 --- a/src/ch2/quicksort.rs +++ b/src/ch2/quicksort.rs @@ -1,7 +1,7 @@ // #[cfg(test)] pub mod tests { - use compiler::{ backend::*, middle::ir::instruction::binary_inst::Add }; - use var::{ ArrVar, Str, Var }; + use compiler::{backend::*, middle::ir::instruction::binary_inst::Add}; + use var::{ArrVar, Str, Var}; #[test] pub fn quicksort_example() { @@ -40,7 +40,7 @@ pub mod tests { mva0s1, callquicksort, addia1s01, - bgea1s2lbb0_17 + bgea1s2lbb0_17, ] ); @@ -184,7 +184,7 @@ pub mod tests { sds20sp, sdra24sp, /* lla s0 arr */ - callquicksort /* lla s1 LC0 */ + callquicksort, /* lla s1 LC0 */ /* lla s2, arr+40 */ ] ); @@ -217,7 +217,7 @@ pub mod tests { lds20sp, lia00, addispsp32, - ret + ret, ] ); let mut Main = Func::new("main".into(), Vec::new(), entry); @@ -243,7 +243,7 @@ pub mod tests { (6, 6), (7, 5), (8, 7), - (9, 9) + (9, 9), ], is_const: false, });