rv_decoder/
lib.rs

1#![allow(warnings, unused)]
2
3/// Takes a RISC-V 32-bit binary instruction and returns the decoded assembly instruction
4///
5/// # Examples:
6///
7/// let mut instr = Vec::new();
8/// instr = ["1", "1", "1", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "0", "0", "0", "0", "1", "0", "0", "0", "1", "0", "0", "1", "1"];
9/// assert_eq!("Add Immediate (ADDI) instruction decoded", rv_decoder::instruction_decoder(instr));
10
11pub fn convert_binary_string_to_vector(binary_string: &str) -> Vec<String> {
12    let mut vector = Vec::new();
13    for i in 0..binary_string.len() {
14      vector.push(binary_string.chars().nth(i).unwrap().to_string());
15    }
16    return vector;
17  }
18
19fn rm_decoder(rm_slice_joined: &str) -> String {
20    match rm_slice_joined {
21        "000" => {
22            return "RNE".to_string(); // Round to nearest, ties to even
23        }
24        "001" => {
25            return "RTZ".to_string(); // Round towards zero
26        }
27        "010" => {
28            return "RDN".to_string(); // Round down (towards negative infinity)
29        }
30        "011" => {
31            return "RUP".to_string(); // Round up (towards positive infinity)
32        }
33        "100" => {
34            return "RMM".to_string(); // Round to nearest, ties to max magnitude
35        }
36        "101" => {
37            return "Invalid".to_string();
38        }
39        "110" => {
40            return "Invalid".to_string();
41        }
42        "111" => {
43            return "DYN".to_string(); // Dynamic rounding mode 
44        }
45        &_ => todo!()
46    }
47}
48
49
50pub fn instruction_decoder(instr: Vec<String>) -> String {
51    /*
52     * This decoder is based on the RISC-V Unprivileged Spec v2.2
53     *
54     * Instruction breakdown
55     * RV32I Base Instruction Set`
56     * 
57     * Note: imm = offset = immediate value
58     *
59     * R-type 
60     * 31------25 24-----20 19-----15 14-----12 11-------7 6-------0
61     * /func7/     /rs2/     /rs1/     /func3/     /rd/      /opcode/
62     * 0-------6 7-----11 12-----16 17--------19 20-----24 25--------31
63     * /func7/    /rs2/     /rs1/     /func3/      /rd/      /opcode/
64     *  
65     * I-type
66     * 31---------20 19-----15 14-------12 11------7 6--------0
67     * /imm[11:0]/     /rs1/     /func3/     /rd/      /opcode/
68     * 0----------11 12-----16 17-------19 20-----24 25-------31
69     * /imm[11:0]/     /rs1/     /func3/     /rd/      /opcode/ 
70     * 
71     * S-type
72     * 31--------25 24-----20 19-----15 14--------12 11-----------7 6---------0
73     * /imm[11:5]/    /rs2/     /rs1/     /func3/      /imm[4:0]/     /opcode/
74     * 0----------6 7------11 12-----16 17--------19 20----------24 25--------31
75     * /imm[11:5]/    /rs2/      /rs1/    /func3/      /imm[4:0]/     /opcode/
76     * 
77     * B-type
78     * 31------------25 24-----20 19-----15 14-------12 11--------------7 6---------0
79     * /imm[12|10:5]/     /rs2/     /rs1/     /func3/     /imm[4:1|11]/    /opcode/
80     * 0--------------6 7------11 12-----16 17-------19 20-------------24 25--------31
81     * /imm[12|10:5]/     /rs2/     /rs1/     /func3/      /imm[4:1|11]/    /opcode/
82     * 
83     * U-type
84     * 31-----------12 11-------7 6---------0
85     * /imm[31:12]/       /rd/     /opcode/
86     * 0------------19 20------24 25--------31
87     * /imm[31:12]/       /rd/      /opcode/
88     * 
89     * J-type
90     * 31----------------------12 11------7 6----------0
91     * /imm[20|10:1|11|19:12]/      /rd/      /opcode/
92     * 0-----------------------19 20-----24 25--------31
93     * /imm[20|10:1|11|19:12]/      /rd/      /opcode/ 
94     *                               
95     * 
96     * RV32A Atomic Instruction Breakdown
97     * 
98     * 31--------27 26----- 25-----  24-----20 19------15 14-------12 11------7 6--------0
99     *   /func5/      /aq/    /rl/     /rs2/     /rs1/      /func3/      /rd/    /opcode/
100     * 0---------4  5------ 6------  7------11 12------16 17-------19 20-----24 25-------31
101     *   /func5/      /aq/    /rl/     /rs2/     /rs1/      /func3/      /rd/    /opcode/
102     * 
103     * RV32F/RV32D Instruction Breakdown
104     * 
105     * 31------27 26----25  24-----20 19------15 14----12 11----7 6--------0
106     *   /rs3/      /00/      /rs2/     /rs1/      /rm/     /rd/   /opcode/
107     * 0-------4  5-----6  7------11 12------16 17-----19 20----24 25-------31
108     *  /rs3/      /00/      /rs2/     /rs1/      /rm/     /rd/     /opcode/
109     * 
110     */
111
112    let opcode_slice = &instr[25..];    // opcode field
113    let opcode_slice_joined = opcode_slice.join("");
114
115    println!("--------------------------------");
116
117    match opcode_slice_joined.as_str() {
118        "0000011" => {      // Load Instructions
119            let funct3_slice = &instr[17..20];
120            let funct3_slice_joined = funct3_slice.join("");
121            let rd_slice = &instr[20..25];
122            let rd_slice_joined = rd_slice.join("");
123            let rs1_slice = &instr[12..17];
124            let rs1_slice_joined = rs1_slice.join("");
125            let mut imm_slice = &instr[0..12];
126            let mut imm_slice_joined = imm_slice.join("");
127
128            let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
129            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
130            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
131
132            // Immediate generator/handler
133            if imm_slice[0] == "1" {
134                let mut x = 1;
135                loop {
136                    let mut twos = i32::pow(2, x);
137                    if (imm_bits as f32)/(twos as f32) < 1.0 {
138                        imm_bits = imm_bits - twos;
139                        break;
140                    }
141                    else {
142                        x = x + 1;
143                    }
144                }
145            }
146
147            match funct3_slice_joined.as_str() {
148                "000" => {      // Load Byte (8-bits)
149                    println!("Load Byte (LB) instruction decoded");
150                    println!("Destination Register address: x{}", rd_bits);
151                    println!("Register One address: x{}", rs1_bits);
152                    println!("Immediate value: {}", imm_bits);
153                    println!("LB x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
154                    println!("--------------------------------");
155                    return format!("LB x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
156                }
157                "001" => {      // Load Half-word (16-bits)
158                    println!("Load Half-word (LH) instruction decoded");
159                    println!("Destination Register address: x{}", rd_bits);
160                    println!("Register One address: x{}", rs1_bits);
161                    println!("Immediate value: {}", imm_bits);
162                    println!("LH x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
163                    println!("--------------------------------");
164                    return format!("LH x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
165                }
166                "010" => {      // Load Word (32-bits)
167                    println!("Load Word (LW) instruction decoded");
168                    println!("Destination Register address: x{}", rd_bits);
169                    println!("Register One address: x{}", rs1_bits);
170                    println!("Immediate value: {}", imm_bits);
171                    println!("LW x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
172                    println!("--------------------------------");
173                    return format!("LW x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
174                }
175                "100" => {      // Load Byte Unsigned (u8-bits)
176                    println!("Load Byte Unsigned (LBU) instruction decoded");
177                    println!("Destination Register address: x{}", rd_bits);
178                    println!("Register One address: x{}", rs1_bits);
179                    println!("Immediate value: {}", imm_bits);
180                    println!("LBU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
181                    println!("--------------------------------");
182                    return format!("LBU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
183                }
184                "101" => {      // Load Half-word Unsigned (u16-bits)
185                    println!("Load Half-word Unsigned (LHU) instruction decoded");
186                    println!("Destination Register address: x{}", rd_bits);
187                    println!("Register One address: x{}", rs1_bits);
188                    println!("Immediate value: {}", imm_bits);
189                    println!("LHU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
190                    println!("--------------------------------");
191                    return format!("LHU x{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
192                }
193                default => {
194                    panic!("Instruction format error!");
195                }
196            &_ => todo!()
197            }
198        }
199
200        "0100011" => {      // Store Instructions
201            let funct3_slice = &instr[17..20];
202            let funct3_slice_joined = funct3_slice.join("");
203            let rs2_slice = &instr[7..12];
204            let rs2_slice_joined = rs2_slice.join("");
205            let rs1_slice = &instr[12..17];
206            let rs1_slice_joined = rs1_slice.join("");
207            let mut imm_slice = &instr[0..7];
208            let mut imm_slice_joined = imm_slice.join("");
209            let imm2_slice = &instr[20..25];
210            let imm2_slice_joined = imm2_slice.join("");
211
212            imm_slice_joined = imm_slice_joined + &imm2_slice_joined;
213            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
214            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
215            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
216
217            // Immediate generator/handler
218            if imm_slice[0] == "1" {
219                let mut x = 1;
220                loop {
221                    let mut twos = i32::pow(2, x);
222                    if (imm_bits as f32)/(twos as f32) < 1.0 {
223                        imm_bits = imm_bits - twos;
224                        break;
225                    }
226                    else {
227                        x = x + 1;
228                    }
229                }
230            }
231
232            match funct3_slice_joined.as_str() {
233                "000" => {      // Store Byte (8-bits)
234                    println!("Store Byte (SB) instruction decoded");
235                    println!("Register One address: x{}", rs1_bits);
236                    println!("Register Two address: x{}", rs2_bits);
237                    println!("Immediate value: {}", imm_bits);
238                    println!("SB x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
239                    println!("--------------------------------");
240                    return format!("SB x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
241                }
242                "001" => {      // Store Half-word (16-bit)
243                    println!("Store Half-word (SH) instruction decoded");
244                    println!("Register One address: x{}", rs1_bits);
245                    println!("Register Two address: x{}", rs2_bits);
246                    println!("Immediate value: {}", imm_bits);
247                    println!("SH x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
248                    println!("--------------------------------");
249                    return format!("SH x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
250                }
251                "010" => {      // Store Word (32-bit)
252                    println!("Store Word (SW) instruction decoded");
253                    println!("Register One address: x{}", rs1_bits);
254                    println!("Register Two address: x{}", rs2_bits);
255                    println!("Immediate value: {}", imm_bits);
256                    println!("SW x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
257                    println!("--------------------------------");
258                    return format!("SW x{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
259                }
260                default => {
261                    panic!("Instruction format error!");
262                }
263            &_ => todo!()
264            }
265        }
266
267        "1100011" =>{
268            let funct3_slice = &instr[17..20];
269            let funct3_slice_joined = funct3_slice.join("");
270            let rs1_slice = &instr[12..17];
271            let rs1_slice_joined = rs1_slice.join("");
272            let rs2_slice = &instr[7..12];
273            let rs2_slice_joined = rs2_slice.join("");
274            let imm1_slice = &instr[0..7];
275            let imm2_slice = &instr[20..25];
276            let imm_slice_1 = imm1_slice[0].to_string(); // imm [12]
277            let imm_slice_2 = &imm1_slice[1..7]; // imm [10:5]
278            let imm_slice_2_joined = imm_slice_2.join("");
279            let imm_slice_3 = &imm2_slice[0..4]; // imm [4:1]
280            let imm_slice_3_joined = imm_slice_3.join("");
281            let imm_slice_4 = imm2_slice[4].to_string(); // imm [11]
282            let zero = "0".to_string();
283            let mut imm_final = imm_slice_1.clone() + &imm_slice_4 + &imm_slice_2_joined + &imm_slice_3_joined + &zero;
284
285            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
286            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
287            let mut imm_bits = i32::from_str_radix(&imm_final, 2).unwrap();
288
289            // Immediate generator/handler
290            if imm_slice_1 == "1" {
291                let mut x = 1;
292                loop {
293                    let mut twos = i32::pow(2, x);
294                    if (imm_bits as f32)/(twos as f32) < 1.0 {
295                        imm_bits = imm_bits - twos;
296                        break;
297                    }
298                    else {
299                        x = x + 1;
300                    }
301                }
302            }
303
304            match funct3_slice_joined.as_str() {
305                "000" => {      // Branch Equal
306                    println!("Branch Equal (BEQ) instruction decoded");
307                    println!("Register One address: x{}", rs1_bits);
308                    println!("Register Two address: x{}", rs2_bits);
309                    println!("Immediate value: {}", imm_bits);
310                    println!("BEQ x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
311                    println!("--------------------------------");
312                    return format!("BEQ x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
313                }
314                "001" => {      // Branch Not Equal
315                    println!("Branch Not Equal (BNE) instruction decoded");
316                    println!("Register One address: x{}", rs1_bits);
317                    println!("Register Two address: x{}", rs2_bits);
318                    println!("Immediate value: {}", imm_bits);
319                    println!("BNE x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
320                    println!("--------------------------------");
321                    return format!("BNE x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
322                }
323                "100" => {      // Branch Less Than
324                    println!("Branch Less Than (BLT) instruction decoded");
325                    println!("Register One address: x{}", rs1_bits);
326                    println!("Register Two address: x{}", rs2_bits);
327                    println!("Immediate value: {}", imm_bits);
328                    println!("BLT x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
329                    println!("--------------------------------");
330                    return format!("BLT x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
331                }
332                "101" => {      // Branch Greater Than or Equal
333                    println!("Branch Greater Than or Equal (BGE) instruction decoded");
334                    println!("Register One address: x{}", rs1_bits);
335                    println!("Register Two address: x{}", rs2_bits);
336                    println!("Immediate value: {}", imm_bits);
337                    println!("BGE x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
338                    println!("--------------------------------");
339                    return format!("BGE x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
340                }
341                "110" => {      // Branch Less Than Unsigned
342                    println!("Branch Less Than Unsigned (BLTU) instruction decoded");
343                    println!("Register One address: x{}", rs1_bits);
344                    println!("Register Two address: x{}", rs2_bits);
345                    println!("Immediate value: {}", imm_bits);
346                    println!("BLTU x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
347                    println!("--------------------------------");
348                    return format!("BLTU x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
349                }
350                "111" => {      // Branch Greater Than or Equal Unsigned
351                    println!("Branch Greater Than or Equal Unsigned (BGEU) instruction decoded");
352                    println!("Register One address: x{}", rs1_bits);
353                    println!("Register Two address: x{}", rs2_bits);
354                    println!("Immediate value: {}", imm_bits);
355                    println!("BGEU x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
356                    println!("--------------------------------");
357                    return format!("BGEU x{}, x{}, {}", rs1_bits, rs2_bits, imm_bits);
358                }
359                default => {
360                    panic!("Instruction format error!");
361                }
362            &_ => todo!()
363            }
364        }
365
366        "0010011" => {      // Immediate type instructions
367            let funct3_slice = &instr[17..20];
368            let funct3_slice_joined = funct3_slice.join("");
369            let rd_slice = &instr[20..25];
370            let rd_slice_joined = rd_slice.join("");
371            let rs1_slice = &instr[12..17];
372            let rs1_slice_joined = rs1_slice.join("");
373            let imm_slice = &instr[0..12];
374            let mut imm_slice_joined = imm_slice.join("");
375
376            let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
377            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
378            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
379
380            // Immediate generator/handler
381            if imm_slice[0] == "1" {
382                let mut x = 1;
383                loop {
384                    let mut twos = i32::pow(2, x);
385                    if  (imm_bits as f32)/(twos as f32) < 1.0 {
386                        imm_bits = imm_bits - twos;
387                        break;
388                    }
389                    else {
390                        x = x + 1;
391                    }
392                }
393            }
394
395            match funct3_slice_joined.as_str() {
396                "000" => {      // Add immediate
397                    println!("Add Immediate (ADDI) instruction decoded");
398                    println!("Destination Register address: x{}", rd_bits);
399                    println!("Register One address: x{}", rs1_bits);
400                    println!("Immediate value: {}", imm_bits);
401                    println!("ADDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
402                    println!("--------------------------------");
403                    return format!("ADDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
404                }
405                "010" => {      // Set less than immediate
406                    println!("Set less than Immediate (SLTI) instruction decoded");
407                    println!("Destination Register address: x{}", rd_bits);
408                    println!("Register One address: x{}", rs1_bits);
409                    println!("Immediate value: {}", imm_bits);
410                    println!("SLTI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
411                    println!("--------------------------------");
412                    return format!("SLTI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
413                }
414                "011" => {      // Set less than immediate unsigned
415                    println!("Set less than Immediate unsigned (SLTIU) instruction decoded");
416                    println!("Destination Register address: x{}", rd_bits);
417                    println!("Register One address: x{}", rs1_bits);
418                    println!("Immediate value: {}", imm_bits);
419                    println!("SLTIU x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
420                    println!("--------------------------------");
421                    return format!("SLTIU x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
422                }
423                "100" => {      // XOR Immediate
424                    println!("XOR Immediate (XORI) instruction decoded");
425                    println!("Destination Register address: x{}", rd_bits);
426                    println!("Register One address: x{}", rs1_bits);
427                    println!("Immediate value: {}", imm_bits);
428                    println!("XORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
429                    println!("--------------------------------");
430                    return format!("XORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
431                }
432                "110" => {      // OR Immediate
433                    println!("OR Immediate (ORI) instruction decoded");
434                    println!("Destination Register address: x{}", rd_bits);
435                    println!("Register One address: x{}", rs1_bits);
436                    println!("Immediate value: {}", imm_bits);
437                    println!("ORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
438                    println!("--------------------------------");
439                    return format!("ORI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
440                }
441                "111" => {      // AND Immediate
442                    println!("AND Immediate (ANDI) instruction decoded");
443                    println!("Destination Register address: x{}", rd_bits);
444                    println!("Register One address: x{}", rs1_bits);
445                    println!("Immediate value: {}", imm_bits);
446                    println!("ANDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
447                    println!("--------------------------------");
448                    return format!("ANDI x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
449                }
450                default => {
451                    panic!("Instruction format error!");
452                }
453            &_ => todo!()
454            }
455        }
456
457        "0110111" => {      // Load upper immediate
458            let rd_slice = &instr[20..25];
459            let rd_slice_joined = rd_slice.join("");
460            let imm_slice = &instr[0..20];
461            let imm_slice_joined = imm_slice.join("");
462
463            let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
464            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
465
466            // Immediate generator/handler
467            if imm_slice[0] == "1" {
468                let mut x = 1;
469                loop {
470                    let mut twos = i32::pow(2, x);
471                    if  (imm_bits as f32)/(twos as f32) < 1.0 {
472                        imm_bits = imm_bits - twos;
473                        break;
474                    }
475                    else {
476                        x = x + 1;
477                    }
478                }
479            }
480
481            println!("Load Upper Immediate (LUI) instruction decoded");
482            println!("Destination Register address: x{}", rd_bits);
483            println!("Immediate address: x{}", imm_bits);
484            println!("LUI x{}, {}", rd_bits, imm_bits);
485            println!("--------------------------------");
486            return format!("LUI x{}, {}", rd_bits, imm_bits);
487        }
488
489        "0010111" => {      // Add upper immediate with PC
490            let rd_slice = &instr[20..25];
491            let rd_slice_joined = rd_slice.join("");
492            let imm_slice = &instr[0..20];
493            let imm_slice_joined = imm_slice.join("");
494
495            let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
496            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
497
498            // Immediate generator/handler
499            if imm_slice[0] == "1" {
500                let mut x = 1;
501                loop {
502                    let mut twos = i32::pow(2, x);
503                    if  (imm_bits as f32)/(twos as f32) < 1.0 {
504                        imm_bits = imm_bits - twos;
505                        break;
506                    }
507                    else {
508                        x = x + 1;
509                    }
510                }
511            }
512
513            println!("Add upper immediate with PC (AUIPC) instruction decoded");
514            println!("Destination Register address: x{}", rd_bits);
515            println!("Immediate address: x{}", imm_bits);
516            println!("AUIPC x{}, {}", rd_bits, imm_bits);
517            println!("--------------------------------");
518            return format!("AUIPC x{}, {}", rd_bits, imm_bits);
519        }
520
521        "1101111" => {      // Jump and link
522            let rd_slice = &instr[20..25];
523            let rd_slice_joined = rd_slice.join("");
524            let imm_slice = &instr[0..20];                      // imm[20:1]
525            let mut imm_slice_offset = &imm_slice[0..12];
526            let imm_slice_joined = imm_slice_offset.join("");
527
528            let rd_bits = u32::from_str_radix(&rd_slice_joined, 2).unwrap();
529            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
530
531            // Immediate generator/handler
532            if imm_slice[0] == "1" {
533                let mut x = 1;
534                loop {
535                    let mut twos = i32::pow(2, x);
536                    if  (imm_bits as f32)/(twos as f32) < 1.0 {
537                        imm_bits = imm_bits - twos;
538                        break;
539                    }
540                    else {
541                        x = x + 1;
542                    }
543                }
544            }
545
546            println!("Jump and Link (JAL) instruction decoded");
547            println!("Destination Register address: x{}", rd_bits);
548            println!("Immediate address: {}", imm_bits);
549            println!("JAL x{}, {}", rd_bits, imm_bits);
550            println!("--------------------------------");
551            return format!("JAL x{}, {}", rd_bits, imm_bits);
552        }
553
554        "1100111" => {      // Jump and link to register
555            let rd_slice = &instr[20..25];
556            let rd_slice_joined = rd_slice.join("");
557            let imm_slice = &instr[0..12];
558            let imm_slice_joined = imm_slice.join("");
559            let rs1_slice = &instr[12..17];
560            let rs1_slice_joined = rs1_slice.join("");
561
562            let rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
563            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
564            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
565
566            // Immediate generator/handler
567            if imm_slice[0] == "1" {
568                let mut x = 1;
569                loop {
570                    let mut twos = i32::pow(2, x);
571                    if  (imm_bits as f32)/(twos as f32) < 1.0 {
572                        imm_bits = imm_bits - twos;
573                        break;
574                    }
575                    else {
576                        x = x + 1;
577                    }
578                }
579            }
580
581            println!("Jump and Link to register (JALR) instruction decoded");
582            println!("Destination Register address: x{}", rd_bits);
583            println!("Register one address: x{}", rs1_bits);
584            println!("Immediate value: {}", imm_bits);
585            println!("JALR x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
586            println!("--------------------------------");
587            return format!("JALR x{}, x{}, {}", rd_bits, rs1_bits, imm_bits);
588        }
589
590        "0110011" => {      // Arithmetic instructions
591            let funct3_slice = &instr[17..20];
592            let funct3_slice_joined = funct3_slice.join("");
593            let funct7_slice = &instr[0..7];
594            let funct7_slice_joined = funct7_slice.join("");
595            let rs2_slice = &instr[7..12];
596            let rs2_slice_joined = rs2_slice.join("");
597            let rs1_slice = &instr[12..17];
598            let rs1_slice_joined = rs1_slice.join("");
599            let rd_slice = &instr[20..25];
600            let rd_slice_joined = rd_slice.join("");
601
602            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
603            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
604            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
605
606            match funct3_slice_joined.as_str() {
607                "000" => {
608                    match funct7_slice_joined.as_str() {
609                        "0000000" => {      // Add
610                            println!("Addition (ADD) instruction decoded");
611                            println!("Destination Register address: x{}", rd_bits);
612                            println!("Register One address: x{}", rs1_bits);
613                            println!("Register Two value: {}", rs2_bits);
614                            println!("ADD x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
615                            println!("--------------------------------");
616                            return format!("ADD x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
617                        }
618                        "0100000" => {      // Sub
619                            println!("Subtraction (SUB) instruction decoded");
620                            println!("Destination Register address: x{}", rd_bits);
621                            println!("Register One address: x{}", rs1_bits);
622                            println!("Register Two value: {}", rs2_bits);
623                            println!("SUB x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
624                            println!("--------------------------------");
625                            return format!("SUB x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
626                        }
627                        "0000001" => {      // Multiply signed rs1 and rs2
628                            println!("Multiplication (MUL) instruction decoded");
629                            println!("Destination Register address: x{}", rd_bits);
630                            println!("Register One address: x{}", rs1_bits);
631                            println!("Register Two value: {}", rs2_bits);
632                            println!("MUL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
633                            println!("--------------------------------");
634                            return format!("MUL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
635                        }
636                        &_ => todo!()
637                    }
638                }
639                "001" => {      
640                    match funct7_slice_joined.as_str() {
641                        "0000000" => {      // Shift left logical
642                            println!("Shift Left Logical (SLL) instruction decoded");
643                            println!("Destination Register address: x{}", rd_bits);
644                            println!("Register One address: x{}", rs1_bits);
645                            println!("Register Two value: {}", rs2_bits);
646                            println!("SLL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
647                            println!("--------------------------------");
648                            return format!("SLL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
649                        }
650                        "0000001" => {      // Multiply high signed rs1 and rs2
651                            println!("Multiply High Signed (MULH) instruction decoded");
652                            println!("Destination Register address: x{}", rd_bits);
653                            println!("Register One address: x{}", rs1_bits);
654                            println!("Register Two value: {}", rs2_bits);
655                            println!("MULH x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
656                            println!("--------------------------------");
657                            return format!("MULH x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
658                        }
659                        &_ => todo!()
660                    }
661                }
662                "010" => {      
663                    match funct7_slice_joined.as_str() {
664                        "0000000" => {      // Set less than
665                            println!("Set less than (SLT) instruction decoded");
666                            println!("Destination Register address: x{}", rd_bits);
667                            println!("Register One address: x{}", rs1_bits);
668                            println!("Register Two value: {}", rs2_bits);
669                            println!("SLT x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
670                            println!("--------------------------------");
671                            return format!("SLT x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
672                        }
673                        "0000001" => {      // Multiply signed rs1 and unsigned rs2
674                            println!("Multiply High Unsigned with signed (MULHSU) instruction decoded");
675                            println!("Destination Register address: x{}", rd_bits);
676                            println!("Register One address: x{}", rs1_bits);
677                            println!("Register Two value: {}", rs2_bits);
678                            println!("MULHSU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
679                            println!("--------------------------------");
680                            return format!("MULHSU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
681                        }
682                        &_ => todo!()
683                    }
684                }
685                "011" => {      
686                    match funct7_slice_joined.as_str() {
687                        "0000000" => {      // Set less than unsigned
688                            println!("Set less than unsigned (SLTU) instruction decoded");
689                            println!("Destination Register address: x{}", rd_bits);
690                            println!("Register One address: x{}", rs1_bits);
691                            println!("Register Two value: {}", rs2_bits);
692                            println!("SLTU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
693                            println!("--------------------------------");
694                            return format!("SLTU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
695                        }
696                        "0000001" => {      // Multiply unsigned rs1 and rs2
697                            println!("Multiply High Unsigned (MULHU) instruction decoded");
698                            println!("Destination Register address: x{}", rd_bits);
699                            println!("Register One address: x{}", rs1_bits);
700                            println!("Register Two value: {}", rs2_bits);
701                            println!("MULHU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
702                            println!("--------------------------------");
703                            return format!("MULHU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
704                        }
705                        &_ => todo!()
706                    }
707                }
708                "100" => {      
709                    match funct7_slice_joined.as_str() {
710                        "0000000" => {      // XOR
711                            println!("XOR instruction decoded");
712                            println!("Destination Register address: x{}", rd_bits);
713                            println!("Register One address: x{}", rs1_bits);
714                            println!("Register Two value: {}", rs2_bits);
715                            println!("XOR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
716                            println!("--------------------------------");
717                            return format!("XOR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
718                        }
719                        "0000001" => {      // Divide signed rs1 and rs2 (rounding towards zero)
720                            println!("Divide Signed (DIV) instruction decoded");
721                            println!("Destination Register address: x{}", rd_bits);
722                            println!("Register One address: x{}", rs1_bits);
723                            println!("Register Two address: x{}", rs2_bits);
724                            println!("DIV x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
725                            println!("--------------------------------");
726                            return format!("DIV x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
727                        }
728                        &_ => todo!()
729                    }
730                }
731                "101" => {      // Shift right
732                    match funct7_slice_joined.as_str() {
733                        "0000000" => {      // Shift right logical
734                            println!("Shift Right Logical (SRL) instruction decoded");
735                            println!("Destination Register address: x{}", rd_bits);
736                            println!("Register One address: x{}", rs1_bits);
737                            println!("Register Two value: {}", rs2_bits);
738                            println!("SRL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
739                            println!("--------------------------------");
740                            return format!("SRL x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
741                        }
742                        "0000001" => {      // Divide unsigned rs1 and rs2 (rounding towards zero)
743                            println!("Divide Unsigned (DIVU) instruction decoded");
744                            println!("Destination Register address: x{}", rd_bits);
745                            println!("Register One address: x{}", rs1_bits);
746                            println!("Register Two address: x{}", rs2_bits);
747                            println!("DIVU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
748                            println!("--------------------------------");
749                            return format!("DIVU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
750                        }
751                        "0100000" => {      // Shift right arithmetic
752                            println!("Shift Right Arithmetic (SRA) instruction decoded");
753                            println!("Destination Register address: x{}", rd_bits);
754                            println!("Register One address: x{}", rs1_bits);
755                            println!("Register Two value: {}", rs2_bits);
756                            println!("SRA x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
757                            println!("--------------------------------");
758                            return format!("SRA x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
759                        }
760                        &_ => todo!()
761                    }
762                }
763                "110" => {      
764                    match funct7_slice_joined.as_str() {
765                        "0000000" => {      // OR
766                            println!("OR instruction decoded");
767                            println!("Destination Register address: x{}", rd_bits);
768                            println!("Register One address: x{}", rs1_bits);
769                            println!("Register Two value: {}", rs2_bits);
770                            println!("OR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
771                            println!("--------------------------------");
772                            return format!("OR x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
773                        }
774                        "0000001" => {      // Remainder signed rs1 and rs2
775                            println!("Remainder Signed (REM) instruction decoded");
776                            println!("Destination Register address: x{}", rd_bits);
777                            println!("Register One address: x{}", rs1_bits);
778                            println!("Register Two address: x{}", rs2_bits);
779                            println!("REM x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
780                            println!("--------------------------------");
781                            return format!("REM x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
782                        }
783                        &_ => todo!()
784                    }
785                }
786                "111" => {      
787                    match funct7_slice_joined.as_str() {
788                        "0000000" => {      // AND
789                            println!("AND instruction decoded");
790                            println!("Destination Register address: x{}", rd_bits);
791                            println!("Register One address: x{}", rs1_bits);
792                            println!("Register Two value: {}", rs2_bits);
793                            println!("AND x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
794                            println!("--------------------------------");
795                            return format!("AND x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
796                        }
797                        "0000001" => {      // Remainder unsigned rs1 and rs2
798                            println!("Remainder Unsigned (REMU) instruction decoded");
799                            println!("Destination Register address: x{}", rd_bits);
800                            println!("Register One address: x{}", rs1_bits);
801                            println!("Register Two address: x{}", rs2_bits);
802                            println!("REMU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
803                            println!("--------------------------------");
804                            return format!("REMU x{}, x{}, x{}", rd_bits, rs1_bits, rs2_bits);
805                        }
806                        &_ => todo!()
807                    }
808                }
809            &_ => todo!()
810            }
811        }
812
813        "0101111" => {
814            let funct5_slice = &instr[0..5];
815            let funct5_slice_joined = funct5_slice.join("");
816            let func3_slice = &instr[17..20];
817            let func3_slice_joined = func3_slice.join("");
818            let aq_slice = &instr[5].to_string();
819            let rl_slice = &instr[6].to_string();
820            let rs2_slice = &instr[7..12];
821            let rs2_slice_joined = rs2_slice.join("");
822            let rs1_slice = &instr[12..17];
823            let rs1_slice_joined = rs1_slice.join("");
824            let rd_slice = &instr[20..25];
825            let rd_slice_joined = rd_slice.join("");
826
827            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
828            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
829            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
830
831            match funct5_slice_joined.as_str() {
832                "00010" => {      // Load Word
833                    println!("Load Word (LR.W) instruction decoded");
834                    println!("Destination Register address: x{}", rd_bits);
835                    println!("Register One address: x{}", rs1_bits);
836                    println!("LR.W x{}, x{}", rd_bits, rs1_bits);
837                    println!("--------------------------------");
838                    return format!("LR.W x{}, x{}", rd_bits, rs1_bits);
839                }
840                "00011" =>{       // Store Word
841                    println!("Store Word (SC.W) instruction decoded");
842                    println!("Destination Register address: x{}", rd_bits);
843                    println!("Register One address: x{}", rs1_bits);
844                    println!("Register Two address: x{}", rs2_bits);
845                    println!("SC.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
846                    println!("--------------------------------");
847                    return format!("SC.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
848                }
849                "00001" =>{       // Atomic Swap
850                    println!("Atomic Swap (AMOSWAP.W) instruction decoded");
851                    println!("Destination Register address: x{}", rd_bits);
852                    println!("Register One address: x{}", rs1_bits);
853                    println!("Register Two address: x{}", rs2_bits);
854                    println!("AMOSWAP.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
855                    println!("--------------------------------");
856                    return format!("AMOSWAP.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
857                }
858                "00000" =>{       // Atomic Add
859                    println!("Atomic Add (AMOADD.W) instruction decoded");
860                    println!("Destination Register address: x{}", rd_bits);
861                    println!("Register One address: x{}", rs1_bits);
862                    println!("Register Two address: x{}", rs2_bits);
863                    println!("AMOADD.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
864                    println!("--------------------------------");
865                    return format!("AMOADD.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
866                }
867                "00100" =>{       // Atomic XOR
868                    println!("Atomic XOR (AMOXOR.W) instruction decoded");
869                    println!("Destination Register address: x{}", rd_bits);
870                    println!("Register One address: x{}", rs1_bits);
871                    println!("Register Two address: x{}", rs2_bits);
872                    println!("AMOXOR.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
873                    println!("--------------------------------");
874                    return format!("AMOXOR.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
875                }
876                "01100" =>{       // Atomic AND
877                    println!("Atomic AND (AMOAND.W) instruction decoded");
878                    println!("Destination Register address: x{}", rd_bits);
879                    println!("Register One address: x{}", rs1_bits);
880                    println!("Register Two address: x{}", rs2_bits);
881                    println!("AMOAND.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
882                    println!("--------------------------------");
883                    return format!("AMOAND.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
884                }
885                "01000" =>{       // Atomic OR
886                    println!("Atomic OR (AMOOR.W) instruction decoded");
887                    println!("Destination Register address: x{}", rd_bits);
888                    println!("Register One address: x{}", rs1_bits);
889                    println!("Register Two address: x{}", rs2_bits);
890                    println!("AMOOR.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
891                    println!("--------------------------------");
892                    return format!("AMOOR.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
893                }
894                "10000" =>{       // Atomic Minimum
895                    println!("Atomic Minimum (AMOMIN.W) instruction decoded");
896                    println!("Destination Register address: x{}", rd_bits);
897                    println!("Register One address: x{}", rs1_bits);
898                    println!("Register Two address: x{}", rs2_bits);
899                    println!("AMOMIN.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
900                    println!("--------------------------------");
901                    return format!("AMOMIN.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
902                }
903                "10100" =>{       // Atomic Maximum
904                    println!("Atomic Maximum (AMOMAX.W) instruction decoded");
905                    println!("Destination Register address: x{}", rd_bits);
906                    println!("Register One address: x{}", rs1_bits);
907                    println!("Register Two address: x{}", rs2_bits);
908                    println!("AMOMAX.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
909                    println!("--------------------------------");
910                    return format!("AMOMAX.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
911                }
912                "11000" =>{       // Atomic Unsigned Minimum
913                    println!("Atomic Unsigned Minimum (AMOMINU.W) instruction decoded");
914                    println!("Destination Register address: x{}", rd_bits);
915                    println!("Register One address: x{}", rs1_bits);
916                    println!("Register Two address: x{}", rs2_bits);
917                    println!("AMOMINU.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
918                    println!("--------------------------------");
919                    return format!("AMOMINU.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
920                }
921                "11100" =>{       // Atomic Unsigned Maximum
922                    println!("Atomic Unsigned Maximum (AMOMAXU.W) instruction decoded");
923                    println!("Destination Register address: x{}", rd_bits);
924                    println!("Register One address: x{}", rs1_bits);
925                    println!("Register Two address: x{}", rs2_bits);
926                    println!("AMOMAXU.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
927                    println!("--------------------------------");
928                    return format!("AMOMAXU.W x{}, x{}, x{}",rd_bits, rs2_bits, rs1_bits);
929                }
930                &_ => todo!()
931            }            
932        }
933
934        "1000011" => {
935            let rs3_slice = &instr[0..5];
936            let rs3_slice_joined = rs3_slice.join("");
937            let funct3_slice = &instr[5..7];
938            let funct3_slice_joined = funct3_slice.join("");
939            let rs2_slice = &instr[7..12];
940            let rs2_slice_joined = rs2_slice.join("");
941            let rs1_slice = &instr[12..17];
942            let rs1_slice_joined = rs1_slice.join("");
943            let rm_slice = &instr[17..20];
944            let rm_slice_joined = rm_slice.join("");
945            let rd_slice = &instr[20..25];
946            let rd_slice_joined = rd_slice.join("");
947            
948            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
949            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
950            let rs3_bits = i32::from_str_radix(&rs3_slice_joined, 2).unwrap();
951            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
952
953            match funct3_slice_joined.as_str() {
954                "00" => {
955                    println!("Floating Point Addition (FMADD.S) instruction decoded");
956                    println!("Destination Register address: f{}", rd_bits);
957                    println!("Register One address: f{}", rs1_bits);
958                    println!("Register Two address: f{}", rs2_bits);
959                    println!("Register Three address: f{}", rs3_bits);
960                    println!("FMADD.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
961                    println!("--------------------------------");
962                    return format!("FMADD.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
963                }
964                "01" => {
965                    println!("Double Floating Point Addition (FMADD.D) instruction decoded");
966                    println!("Destination Register address: f{}", rd_bits);
967                    println!("Register One address: f{}", rs1_bits);
968                    println!("Register Two address: f{}", rs2_bits);
969                    println!("Register Three address: f{}", rs3_bits);
970                    println!("FMADD.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
971                    println!("--------------------------------");
972                    return format!("FMADD.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
973                }
974                &_ => todo!()
975            }
976            
977        }
978
979        "1000111" => {
980            let rs3_slice = &instr[0..5];
981            let rs3_slice_joined = rs3_slice.join("");
982            let funct3_slice = &instr[5..7];
983            let funct3_slice_joined = funct3_slice.join("");
984            let rs2_slice = &instr[7..12];
985            let rs2_slice_joined = rs2_slice.join("");
986            let rs1_slice = &instr[12..17];
987            let rs1_slice_joined = rs1_slice.join("");
988            let rm_slice = &instr[17..20];
989            let rm_slice_joined = rm_slice.join("");
990            let rd_slice = &instr[20..25];
991            let rd_slice_joined = rd_slice.join("");
992           
993            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
994            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
995            let rs3_bits = i32::from_str_radix(&rs3_slice_joined, 2).unwrap();
996            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
997
998            match funct3_slice_joined.as_str() {
999                "00" => {
1000                    println!("Floating Point Subtraction (FMSUB.S) instruction decoded");
1001                    println!("Destination Register address: f{}", rd_bits);
1002                    println!("Register One address: f{}", rs1_bits);
1003                    println!("Register Two address: f{}", rs2_bits);
1004                    println!("Register Three address: f{}", rs3_bits);
1005                    println!("FMSUB.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1006                    println!("--------------------------------");
1007                    return format!("FMSUB.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1008                }
1009                "01" => {
1010                    println!("Double Floating Point Subtraction (FMSUB.D) instruction decoded");
1011                    println!("Destination Register address: f{}", rd_bits);
1012                    println!("Register One address: f{}", rs1_bits);
1013                    println!("Register Two address: f{}", rs2_bits);
1014                    println!("Register Three address: f{}", rs3_bits);
1015                    println!("FMSUB.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1016                    println!("--------------------------------");
1017                    return format!("FMSUB.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1018                }
1019                &_ => todo!()
1020            }
1021        }
1022
1023        "1001011" => {
1024            let rs3_slice = &instr[0..5];
1025            let rs3_slice_joined = rs3_slice.join("");
1026            let funct3_slice = &instr[5..7];
1027            let funct3_slice_joined = funct3_slice.join("");
1028            let rs2_slice = &instr[7..12];
1029            let rs2_slice_joined = rs2_slice.join("");
1030            let rs1_slice = &instr[12..17];
1031            let rs1_slice_joined = rs1_slice.join("");
1032            let rm_slice = &instr[17..20];
1033            let rm_slice_joined = rm_slice.join("");
1034            let rd_slice = &instr[20..25];
1035            let rd_slice_joined = rd_slice.join("");
1036           
1037            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
1038            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
1039            let rs3_bits = i32::from_str_radix(&rs3_slice_joined, 2).unwrap();
1040            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
1041
1042            match funct3_slice_joined.as_str() {
1043                "00" => {
1044                    println!("Floating Point Negative Subtraction (FNMSUB.S) instruction decoded");
1045                    println!("Destination Register address: f{}", rd_bits);
1046                    println!("Register One address: f{}", rs1_bits);
1047                    println!("Register Two address: f{}", rs2_bits);
1048                    println!("Register Three address: f{}", rs3_bits);
1049                    println!("FNMSUB.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1050                    println!("--------------------------------");
1051                    return format!("FNMSUB.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1052                }
1053                "01" => {
1054                    println!("Double Floating Point Negative Subtraction (FNMSUB.D) instruction decoded");
1055                    println!("Destination Register address: f{}", rd_bits);
1056                    println!("Register One address: f{}", rs1_bits);
1057                    println!("Register Two address: f{}", rs2_bits);
1058                    println!("Register Three address: f{}", rs3_bits);
1059                    println!("FNMSUB.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1060                    println!("--------------------------------");
1061                    return format!("FNMSUB.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1062                }
1063                &_ => todo!()
1064            }
1065
1066        }
1067
1068        "1001111" => {
1069            let rs3_slice = &instr[0..5];
1070            let rs3_slice_joined = rs3_slice.join("");
1071            let funct3_slice = &instr[5..7];
1072            let funct3_slice_joined = funct3_slice.join("");
1073            let rs2_slice = &instr[7..12];
1074            let rs2_slice_joined = rs2_slice.join("");
1075            let rs1_slice = &instr[12..17];
1076            let rs1_slice_joined = rs1_slice.join("");
1077            let rm_slice = &instr[17..20];
1078            let rm_slice_joined = rm_slice.join("");
1079            let rd_slice = &instr[20..25];
1080            let rd_slice_joined = rd_slice.join("");
1081           
1082            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
1083            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
1084            let rs3_bits = i32::from_str_radix(&rs3_slice_joined, 2).unwrap();
1085            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
1086
1087            match funct3_slice_joined.as_str() {
1088                "00" => {
1089                    println!("Floating Point Negative Addition (FNMADD.S) instruction decoded");
1090                    println!("Destination Register address: f{}", rd_bits);
1091                    println!("Register One address: f{}", rs1_bits);
1092                    println!("Register Two address: f{}", rs2_bits);
1093                    println!("Register Three address: f{}", rs3_bits);
1094                    println!("FNMADD.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1095                    println!("--------------------------------");
1096                    return format!("FNMADD.S f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1097                }
1098                "01" => {
1099                    println!("Double Floating Point Negative Addition (FNMADD.D) instruction decoded");
1100                    println!("Destination Register address: f{}", rd_bits);
1101                    println!("Register One address: f{}", rs1_bits);
1102                    println!("Register Two address: f{}", rs2_bits);
1103                    println!("Register Three address: f{}", rs3_bits);
1104                    println!("FNMADD.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1105                    println!("--------------------------------");
1106                    return format!("FNMADD.D f{}, f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rs3_bits, rm_decoder(&rm_slice_joined));
1107                }
1108                &_ => todo!()
1109            }
1110        }
1111
1112        "1010011" => {
1113            let rs3_slice = &instr[0..5];
1114            let rs3_slice_joined = rs3_slice.join("");
1115            let funct3_slice = &instr[5..7];
1116            let funct3_slice_joined = funct3_slice.join("");
1117            let rs2_slice = &instr[7..12];
1118            let rs2_slice_joined = rs2_slice.join("");
1119            let rs1_slice = &instr[12..17];
1120            let rs1_slice_joined = rs1_slice.join("");
1121            let rm_slice = &instr[17..20];
1122            let rm_slice_joined = rm_slice.join("");
1123            let rd_slice = &instr[20..25];
1124            let rd_slice_joined = rd_slice.join("");
1125           
1126            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
1127            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
1128            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
1129
1130            match rs3_slice_joined.as_str() {
1131                "00000" => {
1132                    match funct3_slice_joined.as_str() {
1133                        "00" => {
1134                            println!("Floating Point Negative Addition (FADD.S) instruction decoded");
1135                            println!("Destination Register address: f{}", rd_bits);
1136                            println!("Register One address: f{}", rs1_bits);
1137                            println!("Register Two address: f{}", rs2_bits);
1138                            println!("FADD.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1139                            println!("--------------------------------");
1140                            return format!("FADD.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1141                        }
1142                        "01" => {
1143                            println!("Double Floating Point Negative Addition (FADD.D) instruction decoded");
1144                            println!("Destination Register address: f{}", rd_bits);
1145                            println!("Register One address: f{}", rs1_bits);
1146                            println!("Register Two address: f{}", rs2_bits);
1147                            println!("FADD.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1148                            println!("--------------------------------");
1149                            return format!("FADD.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1150                        }
1151                        &_ => todo!()
1152                    }
1153                }
1154                "00001" => {
1155                    match funct3_slice_joined.as_str() {
1156                        "00" => {
1157                            println!("Floating Point Subtraction (FSUB.S) instruction decoded");
1158                            println!("Destination Register address: f{}", rd_bits);
1159                            println!("Register One address: f{}", rs1_bits);
1160                            println!("Register Two address: f{}", rs2_bits);
1161                            println!("FSUB.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1162                            println!("--------------------------------");
1163                            return format!("FSUB.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));  
1164                        }
1165                        "01" => {
1166                            println!("Double Floating Point Subtraction (FSUB.D) instruction decoded");
1167                            println!("Destination Register address: f{}", rd_bits);
1168                            println!("Register One address: f{}", rs1_bits);
1169                            println!("Register Two address: f{}", rs2_bits);
1170                            println!("FSUB.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1171                            println!("--------------------------------");
1172                            return format!("FSUB.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));  
1173                        }
1174                        &_ => todo!()
1175                    }
1176                }
1177                "00010" => {
1178                   match funct3_slice_joined.as_str() {
1179                        "00" => {
1180                            println!("Floating Point Multiplication (FMUL.S) instruction decoded");
1181                            println!("Destination Register address: f{}", rd_bits);
1182                            println!("Register One address: f{}", rs1_bits);
1183                            println!("Register Two address: f{}", rs2_bits);
1184                            println!("FMUL.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1185                            println!("--------------------------------");
1186                            return format!("FMUL.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1187                        }
1188                        "01" => {
1189                            println!("Double Floating Point Multiplication (FMUL.D) instruction decoded");
1190                            println!("Destination Register address: f{}", rd_bits);
1191                            println!("Register One address: f{}", rs1_bits);
1192                            println!("Register Two address: f{}", rs2_bits);
1193                            println!("FMUL.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1194                            println!("--------------------------------");
1195                            return format!("FMUL.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1196                        }
1197                        &_ => todo!()
1198                   }
1199                }
1200                "00011" => {
1201                    match funct3_slice_joined.as_str() {
1202                        "00" => {
1203                            println!("Floating Point Division (FDIV.S) instruction decoded");
1204                            println!("Destination Register address: f{}", rd_bits);
1205                            println!("Register One address: f{}", rs1_bits);
1206                            println!("Register Two address: f{}", rs2_bits);
1207                            println!("FDIV.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1208                            println!("--------------------------------");
1209                            return format!("FDIV.S f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1210                        }
1211                        "01" => {
1212                            println!("Double Floating Point Division (FDIV.D) instruction decoded");
1213                            println!("Destination Register address: f{}", rd_bits);
1214                            println!("Register One address: f{}", rs1_bits);
1215                            println!("Register Two address: f{}", rs2_bits); 
1216                            println!("FDIV.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1217                            println!("--------------------------------");
1218                            return format!("FDIV.D f{}, f{}, f{}, {}", rd_bits, rs1_bits, rs2_bits, rm_decoder(&rm_slice_joined));
1219                        }
1220                        &_ => todo!()
1221                    }
1222                }
1223                "01011" => {
1224                    match funct3_slice_joined.as_str() {
1225                        "00" => {
1226                            println!("Floating Point Square Root (FSQRT.S) instruction decoded");
1227                            println!("Destination Register address: f{}", rd_bits);
1228                            println!("Register One address: f{}", rs1_bits);
1229                            println!("FSQRT.S f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1230                            println!("--------------------------------");
1231                            return format!("FSQRT.S f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1232                        }
1233                        "01" => {
1234                            println!("Double Floating Point Square Root (FSQRT.D) instruction decoded");
1235                            println!("Destination Register address: f{}", rd_bits);
1236                            println!("Register One address: f{}", rs1_bits);
1237                            println!("FSQRT.D f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1238                            println!("--------------------------------");
1239                            return format!("FSQRT.D f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1240                        }
1241                        &_ => todo!()
1242                    }
1243                }
1244                "01000" => {
1245                    match rs2_slice_joined.as_str() {
1246                        "00000" => {
1247                            println!("Double Conversion (FCVT.D.S) instruction decoded");
1248                            println!("Destination Register address: f{}", rd_bits);
1249                            println!("Register One address: f{}", rs1_bits);
1250                            println!("FCVT.D.S f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1251                            println!("--------------------------------");
1252                            return format!("FCVT.D.S f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1253                        }
1254                        "00001" => {
1255                            println!("Double Conversion (FCVT.S.D) instruction decoded");
1256                            println!("Destination Register address: f{}", rd_bits);
1257                            println!("Register One address: f{}", rs1_bits);
1258                            println!("FCVT.S.D f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1259                            println!("--------------------------------");
1260                            return format!("FCVT.S.D f{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1261                        }
1262                        &_ => todo!()
1263                    }
1264                }
1265                "00100" => {
1266                    match rm_slice_joined.as_str() {
1267                            "000" => {
1268                                match funct3_slice_joined.as_str() {
1269                                    "00" => {
1270                                        println!("Floating Point Sign Injection (FSGNJ.S) instruction decoded");
1271                                        println!("Destination Register address: f{}", rd_bits);
1272                                        println!("Register One address: f{}", rs1_bits);
1273                                        println!("Register Two address: f{}", rs2_bits);
1274                                        println!("FSGNJ.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1275                                        println!("--------------------------------");
1276                                        return format!("FSGNJ.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1277                                    }
1278                                    "01" => {
1279                                        println!("Double Sign Injection (FSGNJN.D) instruction decoded");
1280                                        println!("Destination Register address: f{}", rd_bits);
1281                                        println!("Register One address: f{}", rs1_bits);
1282                                        println!("Register Two address: f{}", rs2_bits);
1283                                        println!("FSGNJ.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1284                                        println!("--------------------------------");
1285                                        return format!("FSGNJ.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1286                                    }
1287                                    &_ => todo!()
1288                                }
1289                            }
1290                            "001" => {
1291                                match funct3_slice_joined.as_str() {
1292                                    "00" => {
1293                                        println!("Floating Point Sign Injection (FSGNJN.S) instruction decoded");
1294                                        println!("Destination Register address: f{}", rd_bits);
1295                                        println!("Register One address: f{}", rs1_bits);
1296                                        println!("Register Two address: f{}", rs2_bits);
1297                                        println!("FSGNJN.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1298                                        println!("--------------------------------");
1299                                        return format!("FSGNJN.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1300                                    }
1301                                    "01" => {
1302                                        println!("Double Sign Injection (FSGNJN.D) instruction decoded");
1303                                        println!("Destination Register address: f{}", rd_bits);
1304                                        println!("Register One address: f{}", rs1_bits);
1305                                        println!("Register Two address: f{}", rs2_bits);
1306                                        println!("FSGNJN.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1307                                        println!("--------------------------------");
1308                                        return format!("FSGNJN.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1309                                    }
1310                                    &_ => todo!()
1311                                }
1312                            }
1313                            "010" => {
1314                                match funct3_slice_joined.as_str() {
1315                                    "00" => {
1316                                        println!("Floating Point Sign Injection (FSGNJX.S) instruction decoded");
1317                                        println!("Destination Register address: f{}", rd_bits);
1318                                        println!("Register One address: f{}", rs1_bits);
1319                                        println!("Register Two address: f{}", rs2_bits);
1320                                        println!("FSGNJX.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1321                                        println!("--------------------------------");
1322                                        return format!("FSGNJX.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1323                                    }
1324                                    "01" => {
1325                                        println!("Double Sign Injection (FSGNJX.D) instruction decoded");
1326                                        println!("Destination Register address: f{}", rd_bits);
1327                                        println!("Register One address: f{}", rs1_bits);
1328                                        println!("Register Two address: f{}", rs2_bits);
1329                                        println!("FSGNJX.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits); 
1330                                        println!("--------------------------------");
1331                                        return format!("FSGNJX.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1332                                    }
1333                                    &_ => todo!()
1334                                }
1335                            }
1336                            &_ => todo!()
1337                    }
1338                }
1339                "00101" => {
1340                    match rm_slice_joined.as_str() {
1341                        "000" => {
1342                            match funct3_slice_joined.as_str() {
1343                                "00" => {
1344                                    println!("Floating Point Minimum (FMIN.S) instruction decoded");
1345                                    println!("Destination Register address: f{}", rd_bits);
1346                                    println!("Register One address: f{}", rs1_bits);
1347                                    println!("Register Two address: f{}", rs2_bits);
1348                                    println!("FMIN.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1349                                    println!("--------------------------------");
1350                                    return format!("FMIN.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1351                                }
1352                                "01" => {
1353                                    println!("Double Floating Point Minimum (FMIN.D) instruction decoded");
1354                                    println!("Destination Register address: f{}", rd_bits);
1355                                    println!("Register One address: f{}", rs1_bits);
1356                                    println!("Register Two address: f{}", rs2_bits);
1357                                    println!("FMIN.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1358                                    println!("--------------------------------");
1359                                    return format!("FMIN.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1360                                }
1361                                &_ => todo!()
1362                            }
1363                        }
1364                        "001" => {
1365                            match funct3_slice_joined.as_str() {
1366                                "00" => {
1367                                    println!("Floating Point Maximum (FMAX.S) instruction decoded");
1368                                    println!("Destination Register address: f{}", rd_bits);
1369                                    println!("Register One address: f{}", rs1_bits);
1370                                    println!("Register Two address: f{}", rs2_bits);
1371                                    println!("FMAX.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1372                                    println!("--------------------------------");
1373                                    return format!("FMAX.S f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1374                                }
1375                                "01" => {
1376                                    println!("Double Floating Point Maximum (FMAX.D) instruction decoded");
1377                                    println!("Destination Register address: f{}", rd_bits);
1378                                    println!("Register One address: f{}", rs1_bits);
1379                                    println!("Register Two address: f{}", rs2_bits);
1380                                    println!("FMAX.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1381                                    println!("--------------------------------");
1382                                    return format!("FMAX.D f{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1383                                }
1384                                &_ => todo!()
1385                            }
1386                        }
1387                        &_ => todo!()
1388                    }
1389                }
1390                "11000" => {
1391                    match rs2_slice_joined.as_str() {
1392                        "00000" => {
1393                            match funct3_slice_joined.as_str() {
1394                                "00" => {
1395                                    println!("Floating Point Conversion to Integer (FCVT.W.S) instruction decoded");
1396                                    println!("Destination Register address: x{}", rd_bits);
1397                                    println!("Register One address: f{}", rs1_bits);
1398                                    println!("FCVT.W.S x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1399                                    println!("--------------------------------");
1400                                    return format!("FCVT.W.S x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1401                                }
1402                                "01" => {
1403                                    println!("Double Conversion to Integer (FCVT.W.D) instruction decoded");
1404                                    println!("Destination Register address: x{}", rd_bits);
1405                                    println!("Register One address: f{}", rs1_bits);
1406                                    println!("FCVT.W.D x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1407                                    println!("--------------------------------");
1408                                    return format!("FCVT.W.D x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1409                                }
1410                                &_ => todo!()
1411                            }
1412                        }
1413                        "00001" => {
1414                            match funct3_slice_joined.as_str() {
1415                                "00" => {
1416                                    println!("Floating Point Conversion to Integer (FCVT.WU.S) instruction decoded");
1417                                    println!("Destination Register address: x{}", rd_bits);
1418                                    println!("Register One address: f{}", rs1_bits);
1419                                    println!("FCVT.WU.S x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1420                                    println!("--------------------------------");
1421                                    return format!("FCVT.WU.S x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1422                                }
1423                                "01" => {
1424                                    println!("Double Conversion to Integer (FCVT.WU.D) instruction decoded");
1425                                    println!("Destination Register address: x{}", rd_bits);
1426                                    println!("Register One address: f{}", rs1_bits);
1427                                    println!("FCVT.WU.D x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1428                                    println!("--------------------------------");
1429                                    return format!("FCVT.WU.D x{}, f{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1430                                }
1431                                &_ => todo!()
1432                            }
1433                        }
1434                        &_ => todo!()
1435                    }
1436                }
1437                "11100" => {
1438                    match rm_slice_joined.as_str() {
1439                    "000" => {
1440                        println!("Floating Point Conversion to Integer (FMV.X.W) instruction decoded");
1441                        println!("Destination Register address: x{}", rd_bits);
1442                        println!("Register One address: f{}", rs1_bits);
1443                        println!("FMV.X.W x{}, f{}", rd_bits, rs1_bits);
1444                        println!("--------------------------------");
1445                        return format!("FMV.X.W x{}, f{}", rd_bits, rs1_bits);
1446                    }
1447                    "001" => {
1448                        match funct3_slice_joined.as_str() {
1449                            "00" => {
1450                                println!("Floating Point Class (FCLASS.S) instruction decoded");
1451                                println!("Destination Register address: x{}", rd_bits);
1452                                println!("Register One address: f{}", rs1_bits);
1453                                println!("FCLASS.S x{}, f{}", rd_bits, rs1_bits);
1454                                println!("--------------------------------");
1455                                return format!("FCLASS.S x{}, f{}", rd_bits, rs1_bits);
1456                            }
1457                            "01" => {
1458                                println!("Double Class (FCLASS.D) instruction decoded");
1459                                println!("Destination Register address: x{}", rd_bits);
1460                                println!("Register One address: f{}", rs1_bits);
1461                                println!("FCLASS.D x{}, f{}", rd_bits, rs1_bits);
1462                                println!("--------------------------------");
1463                                return format!("FCLASS.D x{}, f{}", rd_bits, rs1_bits);
1464                            }
1465                            &_ => todo!()
1466                        }
1467                    }
1468                    &_ => todo!()
1469                    }
1470                }
1471                "10100" => {
1472                    match rm_slice_joined.as_str() {
1473                        "000" => {
1474                            match funct3_slice_joined.as_str() {
1475                                "00" => {
1476                                    println!("Floating Point Conversion to Integer (FLE.S) instruction decoded");
1477                                    println!("Destination Register address: x{}", rd_bits);
1478                                    println!("Register One address: f{}", rs1_bits);
1479                                    println!("Register Two address: f{}", rs2_bits);
1480                                    println!("FLE.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1481                                    println!("--------------------------------");
1482                                    return format!("FLE.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1483                                }
1484                                "01" => {
1485                                    println!("Double Conversion to Integer (FLE.D) instruction decoded");
1486                                    println!("Destination Register address: x{}", rd_bits);
1487                                    println!("Register One address: f{}", rs1_bits);
1488                                    println!("Register Two address: f{}", rs2_bits);
1489                                    println!("FLE.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1490                                    println!("--------------------------------");
1491                                    return format!("FLE.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1492                                }
1493                                &_ => todo!()
1494                            }
1495                        }
1496                        "010" => {
1497                            match funct3_slice_joined.as_str() {
1498                                "00" => {
1499                                    println!("Floating Point Conversion to Integer (FEQ.S) instruction decoded");
1500                                    println!("Destination Register address: x{}", rd_bits);
1501                                    println!("Register One address: f{}", rs1_bits);
1502                                    println!("Register Two address: f{}", rs2_bits);
1503                                    println!("FEQ.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1504                                    println!("--------------------------------");
1505                                    return format!("FEQ.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1506                                }
1507                                "01" => {
1508                                    println!("Double Conversion to Integer (FEQ.D) instruction decoded");
1509                                    println!("Destination Register address: x{}", rd_bits);
1510                                    println!("Register One address: f{}", rs1_bits);
1511                                    println!("Register Two address: f{}", rs2_bits);
1512                                    println!("FEQ.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1513                                    println!("--------------------------------");
1514                                    return format!("FEQ.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1515                                }
1516                                &_ => todo!()
1517                            }
1518                        }
1519                        "001" => {
1520                            match funct3_slice_joined.as_str() {
1521                                "00" => {
1522                                    println!("Floating Point Conversion to Integer (FLT.S) instruction decoded");
1523                                    println!("Destination Register address: x{}", rd_bits);
1524                                    println!("Register One address: f{}", rs1_bits);
1525                                    println!("Register Two address: f{}", rs2_bits);
1526                                    println!("FLT.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1527                                    println!("--------------------------------");
1528                                    return format!("FLT.S x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1529                                }
1530                                "01" => {
1531                                    println!("Double Conversion to Integer (FLT.D) instruction decoded");
1532                                    println!("Destination Register address: x{}", rd_bits);
1533                                    println!("Register One address: f{}", rs1_bits);
1534                                    println!("Register Two address: f{}", rs2_bits);
1535                                    println!("FLT.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1536                                    println!("--------------------------------");
1537                                    return format!("FLT.D x{}, f{}, f{}", rd_bits, rs1_bits, rs2_bits);
1538                                }
1539                                &_ => todo!()
1540                            }
1541                        }
1542                        &_ => todo!()
1543                    }
1544                }
1545                "11010" => {
1546                    match rs2_slice_joined.as_str() {
1547                        "00000" => {
1548                            match funct3_slice_joined.as_str() {
1549                                "00" => {
1550                                    println!("Floating Point Conversion to Integer (FCVT.S.W) instruction decoded");
1551                                    println!("Destination Register address: f{}", rd_bits);
1552                                    println!("Register One address: x{}", rs1_bits);
1553                                    println!("FCVT.S.W f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1554                                    println!("--------------------------------");
1555                                    return format!("FCVT.S.W f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1556                                }
1557                                "01" => {
1558                                    println!("Double Conversion to Integer (FCVT.D.W) instruction decoded");
1559                                    println!("Destination Register address: f{}", rd_bits);
1560                                    println!("Register One address: x{}", rs1_bits);
1561                                    println!("FCVT.D.W f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1562                                    println!("--------------------------------");
1563                                    return format!("FCVT.D.W f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1564                                }
1565                                &_ => todo!()
1566                            }
1567                        }
1568                        "00001" => {
1569                            match funct3_slice_joined.as_str() {
1570                                "00" => {
1571                                    println!("Floating Point Conversion to Integer (FCVT.S.WU) instruction decoded");
1572                                    println!("Destination Register address: f{}", rd_bits);
1573                                    println!("Register One address: x{}", rs1_bits);
1574                                    println!("FCVT.S.WU f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1575                                    println!("--------------------------------");
1576                                    return format!("FCVT.S.WU f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1577                                }
1578                                "01" => {
1579                                    println!("Double Conversion to Integer (FCVT.D.WU) instruction decoded");
1580                                    println!("Destination Register address: f{}", rd_bits);
1581                                    println!("Register One address: x{}", rs1_bits);
1582                                    println!("FCVT.D.WU f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1583                                    println!("--------------------------------");
1584                                    return format!("FCVT.D.WU f{}, x{}, {}", rd_bits, rs1_bits, rm_decoder(&rm_slice_joined));
1585                                }
1586                                &_ => todo!()
1587                            }
1588                        }
1589                        &_ => todo!()
1590                    }
1591                }
1592                "11110" => {
1593                    println!("Floating Point Conversion to Integer (FMV.W.X) instruction decoded");
1594                    println!("Destination Register address: f{}", rd_bits);
1595                    println!("Register One address: x{}", rs1_bits);
1596                    println!("FMV.W.X f{}, x{}", rd_bits, rs1_bits);
1597                    println!("--------------------------------");
1598                    return format!("FMV.W.X f{}, x{}", rd_bits, rs1_bits);
1599                }
1600                &_ => todo!()
1601            }
1602
1603        }
1604        "0000111" => {
1605            let imm_slice = &instr[0..12];
1606            let imm_slice_joined = imm_slice.join("");
1607            let rs1_slice = &instr[12..17];
1608            let rs1_slice_joined = rs1_slice.join("");
1609            let rd_slice = &instr[20..25];
1610            let rd_slice_joined = rd_slice.join("");
1611            let rm_slice = &instr[17..20];
1612            let rm_slice_joined = rm_slice.join("");
1613            
1614            let mut rd_bits = i32::from_str_radix(&rd_slice_joined, 2).unwrap();
1615            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
1616            let imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
1617
1618
1619            match rm_slice_joined.as_str() {
1620                "010" => {
1621
1622                    println!("Floating Point Load Word (FLW) instruction decoded");
1623                    println!("Destination Register address: f{}", rd_bits);
1624                    println!("Register One address: x{}", rs1_bits);
1625                    println!("FLW f{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
1626                    println!("--------------------------------");
1627                    return format!("FLW f{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
1628                }
1629                "011" =>{
1630                    println!("Load Double (FLD) instruction decoded");
1631                    println!("Destination Register address: f{}", rd_bits);
1632                    println!("Register One address: x{}", rs1_bits);
1633                    println!("Immendiate: {}", imm_bits);
1634                    println!("FLD f{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
1635                    println!("--------------------------------");
1636                    return format!("FLD f{}, {}(x{})", rd_bits, imm_bits, rs1_bits);
1637                }
1638                &_ => todo!()
1639            }
1640
1641        }
1642        "0100111" => {
1643            let rs2_slice = &instr[7..12];
1644            let rs2_slice_joined = rs2_slice.join("");
1645            let rs1_slice = &instr[12..17];
1646            let rs1_slice_joined = rs1_slice.join("");
1647            let imm1_slice = &instr[0..7];
1648            let imm1_slice_joined = imm1_slice.join("");
1649            let imm2_slice = &instr[20..25];
1650            let imm2_slice_joined = imm2_slice.join("");
1651            let imm_slice_joined = imm1_slice_joined + &imm2_slice_joined;
1652            let rm_slice = &instr[17..20];
1653            let rm_slice_joined = rm_slice.join("");
1654            
1655            let mut imm_bits = i32::from_str_radix(&imm_slice_joined, 2).unwrap();
1656            let rs1_bits = i32::from_str_radix(&rs1_slice_joined, 2).unwrap();
1657            let rs2_bits = i32::from_str_radix(&rs2_slice_joined, 2).unwrap();
1658
1659            match rm_slice_joined.as_str() {
1660                "010" => {
1661                    println!("Floating Point Store Word (FSW) instruction decoded");
1662                    println!("Register One address: f{}", rs1_bits);
1663                    println!("Register Two address: x{}", rs2_bits);
1664                    println!("Immediates: {}", imm_bits);
1665                    println!("FSW f{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
1666                    println!("--------------------------------");
1667                    return format!("FSW f{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
1668                }
1669                "011" => {
1670                    println!("Store Double (FSD) instruction decoded");
1671                    println!("Register One address: f{}", rs1_bits);
1672                    println!("Register Two address: x{}", rs2_bits);
1673                    println!("Immediates: {}", imm_bits);
1674                    println!("FSD f{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
1675                    println!("--------------------------------");
1676                    return format!("FSD f{}, {}(x{})", rs2_bits, imm_bits, rs1_bits);
1677                }
1678                &_ => todo!()
1679            }
1680        }
1681        default => {
1682            panic!("Opcode not found!");
1683        }
1684    &_ => todo!()
1685    }
1686}