MCPcopy Create free account
hub / github.com/LPC4/Full-Stack / expand_li

Function expand_li

crates/asm-to-binary/src/assembler/parser.rs:376–427  ·  view source on GitHub ↗

Expand `li rd, imm` into the minimal real instruction sequence. Handles 12-bit, 32-bit signed, and full 64-bit immediates.

(rd: u8, imm: i64)

Source from the content-addressed store, hash-verified

374 "sb" => AsmToken::Real(RealInstruction::Sb(Sb::new(rs1, rs2, imm))),
375 "sw" => AsmToken::Real(RealInstruction::Sw(Sw::new(rs1, rs2, imm))),
376 "sd" => AsmToken::Real(RealInstruction::Sd(Sd::new(rs1, rs2, imm))),
377 _ => unreachable!(),
378 }
379}
380
381fn load_inst(mnemonic: &str, rd: u8, rs1: u8, imm: i32) -> AsmToken {
382 use crate::riscv::rv64i::Lw;
383 match mnemonic {
384 "lb" => AsmToken::Real(RealInstruction::Lb(Lb::new(rd, rs1, imm))),
385 "lbu" => AsmToken::Real(RealInstruction::Lbu(Lbu::new(rd, rs1, imm))),
386 "lw" => AsmToken::Real(RealInstruction::Lw(Lw::new(rd, rs1, imm))),
387 "ld" => AsmToken::Real(RealInstruction::Ld(Ld::new(rd, rs1, imm))),
388 _ => unreachable!(),
389 }
390}
391
392// Build an I-type ALU immediate `AsmToken` (addi, addiw, andi, ori).
393fn i_imm_inst(mnemonic: &str, rd: u8, rs1: u8, imm: i32) -> AsmToken {
394 match mnemonic {
395 "addi" => AsmToken::Real(RealInstruction::Addi(Addi::new(rd, rs1, imm))),
396 "addiw" => AsmToken::Real(RealInstruction::Addiw(Addiw::new(rd, rs1, imm))),
397 "andi" => AsmToken::Real(RealInstruction::Andi(Andi::new(rd, rs1, imm))),
398 "ori" => AsmToken::Real(RealInstruction::Ori(Ori::new(rd, rs1, imm))),
399 _ => unreachable!(),
400 }
401}
402
403// Build a shift-immediate `AsmToken` (slli, srli, srai).
404fn shift_inst(mnemonic: &str, rd: u8, rs1: u8, shamt: u8) -> AsmToken {
405 match mnemonic {
406 "slli" => AsmToken::Real(RealInstruction::Slli(Slli::new(rd, rs1, shamt))),
407 "srli" => AsmToken::Real(RealInstruction::Srli(Srli::new(rd, rs1, shamt))),
408 "srai" => AsmToken::Real(RealInstruction::Srai(Srai::new(rd, rs1, shamt))),
409 _ => unreachable!(),
410 }
411}
412
413// --- `li` immediate expansion ---
414
415fn try_parse_li(rest: &str) -> Option<Vec<AsmToken>> {
416 let (rd_str, imm_str) = parse_two_fields(rest)?;
417 let rd = parse_int_reg(rd_str)?;
418 let imm = parse_imm_i64(imm_str)?;
419 Some(expand_li(rd, imm))
420}
421
422// Expand `li rd, imm` into the minimal real instruction sequence.
423// Handles 12-bit, 32-bit signed, and full 64-bit immediates.
424fn expand_li(rd: u8, imm: i64) -> Vec<AsmToken> {
425 let mut out = Vec::new();
426
427 // Emit lui+addi for a signed 32-bit value into `rd`.
428 let load32 = |reg: u8, val32: i32, out: &mut Vec<AsmToken>| {
429 if (-2048..=2047).contains(&(val32 as i64)) {
430 out.push(AsmToken::Real(RealInstruction::Addi(Addi::new(

Callers 1

try_parse_liFunction · 0.70

Calls 5

load32Function · 0.85
SlliClass · 0.85
SrliClass · 0.85
pushMethod · 0.80
containsMethod · 0.45

Tested by

no test coverage detected