1pub mod register;
3pub mod memory;
4
5use anyhow::{Result, Context};
6use crate::recompiler::decoder::{DecodedInstruction, InstructionType, Operand};
7use crate::recompiler::analysis::FunctionMetadata;
8use std::collections::HashMap;
9
10pub struct CodeGenerator {
11 indent_level: usize,
12 register_map: HashMap<u8, String>,
13 next_temp: usize,
14 register_values: HashMap<u8, RegisterValue>,
15 label_counter: usize,
16 optimize: bool,
17 function_calls: Vec<u32>, basic_block_map: HashMap<u32, usize>, }
20
21#[derive(Debug, Clone)]
22enum RegisterValue {
23 Constant(u32),
24 Variable(String),
25 Unknown,
26}
27
28impl CodeGenerator {
29 pub fn new() -> Self {
30 Self {
31 indent_level: 0,
32 register_map: HashMap::new(),
33 next_temp: 0,
34 register_values: HashMap::new(),
35 label_counter: 0,
36 optimize: true,
37 function_calls: Vec::new(),
38 basic_block_map: HashMap::new(),
39 }
40 }
41
42 pub fn with_optimizations(mut self, optimize: bool) -> Self {
43 self.optimize = optimize;
44 self
45 }
46
47 pub fn generate_function(
48 &mut self,
49 metadata: &FunctionMetadata,
50 instructions: &[DecodedInstruction],
51 ) -> Result<String> {
52 let mut code = String::new();
53
54 code.push_str(&self.generate_function_signature(metadata)?);
56 code.push_str(" {\n");
57
58 self.indent_level += 1;
59
60 code.push_str(&self.generate_function_body(instructions)?);
62
63 self.indent_level -= 1;
64 code.push_str("}\n");
65
66 Ok(code)
67 }
68
69 fn generate_function_signature(&self, metadata: &FunctionMetadata) -> Result<String> {
70 let mut sig = String::new();
71
72 let func_name = if metadata.name.is_empty() || metadata.name.starts_with("sub_") {
74 format!("func_0x{:08X}", metadata.address)
75 } else {
76 format!("{}_{:08X}", self.sanitize_identifier(&metadata.name), metadata.address)
77 };
78
79 sig.push_str("pub fn ");
80 sig.push_str(&func_name);
81 sig.push_str("(");
82
83 sig.push_str("ctx: &mut CpuContext, memory: &mut MemoryManager");
85
86 sig.push_str(") -> Result<Option<u32>>");
90
91 Ok(sig)
92 }
93
94 fn generate_function_body(&mut self, instructions: &[DecodedInstruction]) -> Result<String> {
95 let cfg = crate::recompiler::analysis::control_flow::ControlFlowAnalyzer::build_cfg(instructions, 0)
97 .unwrap_or_else(|_| {
98 crate::recompiler::analysis::control_flow::ControlFlowGraph {
100 nodes: vec![],
101 edges: vec![],
102 entry_block: 0,
103 }
104 });
105
106 let def_use_chains = crate::recompiler::analysis::data_flow::DataFlowAnalyzer::build_def_use_chains(instructions);
108 let live_analysis = if !cfg.nodes.is_empty() {
109 Some(crate::recompiler::analysis::data_flow::DataFlowAnalyzer::live_variable_analysis(&cfg))
110 } else {
111 None
112 };
113
114 let optimized_instructions = if let Some(ref live) = live_analysis {
116 crate::recompiler::analysis::data_flow::DataFlowAnalyzer::eliminate_dead_code(instructions, live)
117 } else {
118 instructions.to_vec()
119 };
120
121 self.generate_function_body_impl(&optimized_instructions)
122 }
123
124 fn generate_function_body_impl(&mut self, instructions: &[DecodedInstruction]) -> Result<String> {
125 let mut code = String::new();
126
127 code.push('\n');
132
133 if !instructions.is_empty() {
135 code.push_str(&self.indent());
136 code.push_str("// Stack frame setup\n");
137 code.push_str(&self.indent());
138 code.push_str("let stack_base = ctx.get_register(1); // r1 is stack pointer\n");
139 code.push('\n');
140 }
141
142 let mut basic_blocks: Vec<Vec<DecodedInstruction>> = Vec::new();
145 let mut current_block: Vec<DecodedInstruction> = Vec::new();
146
147 for inst in instructions {
148 current_block.push(inst.clone());
149
150 if matches!(inst.instruction.instruction_type, InstructionType::Branch) {
152 basic_blocks.push(current_block);
153 current_block = Vec::new();
154 }
155 }
156
157 if !current_block.is_empty() {
159 basic_blocks.push(current_block);
160 }
161
162 for (block_idx, block) in basic_blocks.iter().enumerate() {
164 if block_idx > 0 {
165 code.push_str(&self.indent());
166 code.push_str(&format!("// Basic block {}\n", block_idx));
167 }
168
169 for (inst_idx, instruction) in block.iter().enumerate() {
170 match self.generate_instruction(instruction) {
171 Ok(inst_code) => {
172 code.push_str(&inst_code);
173 }
174 Err(e) => {
175 code.push_str(&self.indent());
177 code.push_str(&format!(
178 "// Error generating instruction {}: {}\n",
179 inst_idx, e
180 ));
181 code.push_str(&self.indent());
182 code.push_str(&format!("// Raw instruction: 0x{:08X}\n", instruction.raw));
183 code.push_str(&self.indent());
184 code.push_str(&format!("// Instruction type: {:?}\n", instruction.instruction.instruction_type));
185 code.push_str(&self.indent());
186 code.push_str("// Fallback: generating generic instruction handler\n");
187 code.push_str(&self.indent());
188 code.push_str(&format!(
189 "// TODO: Implement proper handling for opcode 0x{:02X}\n",
190 instruction.instruction.opcode
191 ));
192 code.push_str(&self.indent());
193 code.push_str("// Continuing with next instruction...\n");
194
195 if let Ok(fallback) = self.generate_generic(instruction) {
197 code.push_str(&fallback);
198 }
199 }
200 }
201 }
202 }
203
204 if !instructions.is_empty() {
206 code.push('\n');
207 code.push_str(&self.indent());
208 code.push_str("// Stack frame teardown\n");
209 code.push_str(&self.indent());
210 code.push_str("ctx.set_register(1, stack_base);\n");
211 }
212
213 code.push_str(&self.indent());
215 code.push_str("// Return value is in r3 (PowerPC calling convention)\n");
216 code.push_str(&self.indent());
217 code.push_str("Ok(Some(ctx.get_register(3)))\n");
218
219 Ok(code)
220 }
221
222 fn build_basic_blocks<'a>(&self, instructions: &'a [DecodedInstruction]) -> Result<Vec<Vec<&'a DecodedInstruction>>> {
223 let mut blocks = Vec::new();
225 let mut current_block = Vec::new();
226
227 for inst in instructions {
228 current_block.push(inst);
229
230 if matches!(inst.instruction.instruction_type, InstructionType::Branch) {
232 blocks.push(current_block);
233 current_block = Vec::new();
234 }
235 }
236
237 if !current_block.is_empty() {
239 blocks.push(current_block);
240 }
241
242 Ok(blocks)
243 }
244
245 fn generate_instruction(&mut self, inst: &DecodedInstruction) -> Result<String> {
246 let mut code = String::new();
247
248 if self.optimize {
250 code.push_str(&self.indent());
251 code.push_str(&format!("// 0x{:08X}: ", inst.raw));
252 }
253
254 match inst.instruction.instruction_type {
255 InstructionType::Arithmetic => {
256 code.push_str(&self.generate_arithmetic(inst)?);
257 }
258 InstructionType::Load => {
259 code.push_str(&self.generate_load(inst)?);
260 }
261 InstructionType::Store => {
262 code.push_str(&self.generate_store(inst)?);
263 }
264 InstructionType::Branch => {
265 code.push_str(&self.generate_branch(inst)?);
266 }
267 InstructionType::Compare => {
268 code.push_str(&self.generate_compare(inst)?);
269 }
270 InstructionType::Move => {
271 code.push_str(&self.generate_move(inst)?);
272 }
273 InstructionType::System => {
274 code.push_str(&self.generate_system(inst)?);
275 }
276 InstructionType::FloatingPoint => {
277 code.push_str(&self.generate_floating_point(inst)?);
278 }
279 InstructionType::ConditionRegister => {
280 code.push_str(&self.generate_condition_register(inst)?);
281 }
282 InstructionType::Shift => {
283 code.push_str(&self.generate_shift(inst)?);
284 }
285 InstructionType::Rotate => {
286 code.push_str(&self.generate_rotate(inst)?);
287 }
288 _ => {
289 code.push_str(&self.generate_generic(inst)?);
291 }
292 }
293
294 Ok(code)
295 }
296
297 fn generate_arithmetic(&mut self, inst: &DecodedInstruction) -> Result<String> {
298 let mut code = String::new();
299
300 if inst.instruction.operands.len() < 2 {
301 anyhow::bail!("Arithmetic instruction requires at least 2 operands");
302 }
303
304 let rt_reg = match &inst.instruction.operands[0] {
305 Operand::Register(r) => *r,
306 _ => anyhow::bail!("First operand must be a register"),
307 };
308
309 let ra_reg = match &inst.instruction.operands[1] {
310 Operand::Register(r) => *r,
311 _ => anyhow::bail!("Second operand must be a register"),
312 };
313
314 let (op, update_cr) = match inst.instruction.opcode {
316 14 => ("+", false), 15 => ("-", false), 12 => ("&", false), 13 => ("|", false), 10 => ("^", false), 11 => ("&", false), 31 => {
323 let ext_opcode = (inst.raw >> 1) & 0x3FF;
325 match ext_opcode {
326 266 => ("+", false), 40 => ("-", false), 28 => ("&", false), 444 => ("|", false), 316 => ("^", false), 235 => ("*", false), 233 => ("*", false), 104 => ("/", false), 536 => ("<<", false), 824 => (">>", false), 792 => (">>", false), _ => ("+", false),
338 }
339 }
340 _ => ("+", false),
341 };
342
343 let (rb_expr, rb_value) = if inst.instruction.operands.len() > 2 {
345 match &inst.instruction.operands[2] {
346 Operand::Register(r) => {
347 let reg_val = self.get_register_value(*r);
348 (format!("ctx.get_register({})", r), reg_val)
349 }
350 Operand::Immediate(i) => {
351 let val = *i as u32;
352 (format!("{}u32", val), Some(RegisterValue::Constant(val)))
353 }
354 Operand::Immediate32(i) => {
355 let val = *i as u32;
356 (format!("{}u32", val), Some(RegisterValue::Constant(val)))
357 }
358 _ => ("0u32".to_string(), Some(RegisterValue::Constant(0))),
359 }
360 } else {
361 ("0u32".to_string(), Some(RegisterValue::Constant(0)))
362 };
363
364 let operation_code = if op == "<<" || op == ">>" {
366 if op == "<<" {
367 format!("ctx.get_register({}) << ({} & 0x1F)", ra_reg, rb_expr)
368 } else {
369 format!("ctx.get_register({}) >> ({} & 0x1F)", ra_reg, rb_expr)
370 }
371 } else {
372 format!("ctx.get_register({}) {} {}", ra_reg, op, rb_expr)
373 };
374
375 let ra_value = self.get_register_value(ra_reg);
377 if let (Some(RegisterValue::Constant(a)), Some(RegisterValue::Constant(b))) = (ra_value, rb_value) {
378 let result = match op {
379 "+" => a.wrapping_add(b),
380 "-" => a.wrapping_sub(b),
381 "*" => a.wrapping_mul(b),
382 "&" => a & b,
383 "|" => a | b,
384 "^" => a ^ b,
385 "<<" => a << (b & 0x1F),
386 ">>" => a >> (b & 0x1F),
387 _ => a,
388 };
389 code.push_str(&self.indent());
390 code.push_str(&format!(
391 "ctx.set_register({}, {}u32); // Optimized: constant folding\n",
392 rt_reg, result
393 ));
394 self.set_register_value(rt_reg, RegisterValue::Constant(result));
395 } else {
396 code.push_str(&self.indent());
397 code.push_str(&format!(
398 "ctx.set_register({}, {});\n",
399 rt_reg, operation_code
400 ));
401 self.set_register_value(rt_reg, RegisterValue::Unknown);
402 }
403
404 if update_cr {
406 code.push_str(&self.indent());
407 code.push_str(&format!(
408 "let result = ctx.get_register({});\n",
409 rt_reg
410 ));
411 code.push_str(&self.indent());
412 code.push_str("let cr_field = if result == 0 { 0x2u8 } else if (result as i32) < 0 { 0x8u8 } else { 0x4u8 };\n");
413 code.push_str(&self.indent());
414 code.push_str("ctx.set_cr_field(0, cr_field);\n");
415 }
416
417 Ok(code)
418 }
419
420 fn get_register_value(&self, reg: u8) -> Option<RegisterValue> {
421 self.register_values.get(®).cloned()
422 }
423
424 fn set_register_value(&mut self, reg: u8, value: RegisterValue) {
425 self.register_values.insert(reg, value);
426 }
427
428 fn generate_load(&mut self, inst: &DecodedInstruction) -> Result<String> {
429 let mut code = String::new();
430
431 if inst.instruction.operands.len() < 3 {
432 anyhow::bail!("Load instruction requires 3 operands");
433 }
434
435 let rt_reg = match &inst.instruction.operands[0] {
436 Operand::Register(r) => *r,
437 _ => anyhow::bail!("First operand must be a register"),
438 };
439
440 let ra_reg = match &inst.instruction.operands[1] {
441 Operand::Register(r) => *r,
442 _ => anyhow::bail!("Second operand must be a register"),
443 };
444
445 let offset = match &inst.instruction.operands[2] {
446 Operand::Immediate(i) => *i as i32,
447 _ => 0,
448 };
449
450 let base_value = self.get_register_value(ra_reg);
452 if let Some(RegisterValue::Constant(base)) = base_value {
453 let addr = base.wrapping_add(offset as u32);
454 code.push_str(&self.indent());
455 code.push_str(&format!(
456 "let value = memory.read_u32(0x{:08X}u32).unwrap_or(0u32); // Optimized: constant address\n",
457 addr
458 ));
459 } else {
460 code.push_str(&self.indent());
461 code.push_str(&format!(
462 "let addr = ctx.get_register({}) as u32 + {}i32 as u32;\n",
463 ra_reg, offset
464 ));
465 code.push_str(&self.indent());
466 code.push_str("let value = memory.read_u32(addr).unwrap_or(0u32);\n");
467 }
468
469 code.push_str(&self.indent());
470 code.push_str(&format!("ctx.set_register({}, value);\n", rt_reg));
471 self.set_register_value(rt_reg, RegisterValue::Unknown);
472
473 Ok(code)
474 }
475
476 fn generate_store(&mut self, inst: &DecodedInstruction) -> Result<String> {
477 let mut code = String::new();
478
479 if inst.instruction.operands.len() < 3 {
480 anyhow::bail!("Store instruction requires 3 operands");
481 }
482
483 let rs_reg = match &inst.instruction.operands[0] {
484 Operand::Register(r) => *r,
485 _ => anyhow::bail!("First operand must be a register"),
486 };
487
488 let ra_reg = match &inst.instruction.operands[1] {
489 Operand::Register(r) => *r,
490 _ => anyhow::bail!("Second operand must be a register"),
491 };
492
493 let offset = match &inst.instruction.operands[2] {
494 Operand::Immediate(i) => *i as i32,
495 _ => 0,
496 };
497
498 let base_value = self.get_register_value(ra_reg);
500 let value_expr = if let Some(RegisterValue::Constant(val)) = self.get_register_value(rs_reg) {
501 format!("{}u32", val)
502 } else {
503 format!("ctx.get_register({})", rs_reg)
504 };
505
506 if let Some(RegisterValue::Constant(base)) = base_value {
507 let addr = base.wrapping_add(offset as u32);
508 code.push_str(&self.indent());
509 code.push_str(&format!(
510 "memory.write_u32(0x{:08X}u32, {}).unwrap_or(()); // Optimized: constant address\n",
511 addr, value_expr
512 ));
513 } else {
514 code.push_str(&self.indent());
515 code.push_str(&format!(
516 "let addr = ctx.get_register({}) as u32 + {}i32 as u32;\n",
517 ra_reg, offset
518 ));
519 code.push_str(&self.indent());
520 code.push_str(&format!("memory.write_u32(addr, {}).unwrap_or(());\n", value_expr));
521 }
522
523 Ok(code)
524 }
525
526 fn generate_branch(&mut self, inst: &DecodedInstruction) -> Result<String> {
527 let mut code = String::new();
528
529 if inst.instruction.operands.is_empty() {
530 anyhow::bail!("Branch instruction requires operands");
531 }
532
533 match inst.instruction.operands.len() {
535 1 => {
536 let target = match &inst.instruction.operands[0] {
538 Operand::Immediate32(li) => *li,
539 Operand::Address(addr) => *addr as i32,
540 _ => anyhow::bail!("Branch target must be immediate or address"),
541 };
542
543 let is_call = inst.instruction.opcode == 18 && (inst.raw & 1) != 0; if is_call {
547 self.function_calls.push(target as u32);
548 code.push_str(&self.indent());
549 code.push_str(&format!(
550 "// Function call to 0x{:08X}\n",
551 target
552 ));
553 code.push_str(&self.indent());
554 code.push_str("// Save return address in link register\n");
555 code.push_str(&self.indent());
556 code.push_str("let saved_lr = ctx.lr;\n");
557 code.push_str(&self.indent());
558 code.push_str("ctx.lr = ctx.pc + 4;\n");
559 code.push_str(&self.indent());
560 code.push_str("// Call recompiled function via dispatcher\n");
561 code.push_str(&self.indent());
562 code.push_str(&format!(
563 "match call_function_by_address(0x{:08X}u32, ctx, memory) {{\n",
564 target
565 ));
566 self.indent_level += 1;
567 code.push_str(&self.indent());
568 code.push_str("Ok(result) => {\n");
569 self.indent_level += 1;
570 code.push_str(&self.indent());
571 code.push_str("// Function call succeeded, result in r3 (PowerPC calling convention)\n");
572 code.push_str(&self.indent());
573 code.push_str("if let Some(ret_val) = result {\n");
574 self.indent_level += 1;
575 code.push_str(&self.indent());
576 code.push_str("ctx.set_register(3, ret_val); // Return value in r3\n");
577 self.indent_level -= 1;
578 code.push_str(&self.indent());
579 code.push_str("}\n");
580 code.push_str(&self.indent());
581 code.push_str("ctx.lr = saved_lr; // Restore link register\n");
582 self.indent_level -= 1;
583 code.push_str(&self.indent());
584 code.push_str("}\n");
585 code.push_str(&self.indent());
586 code.push_str("Err(e) => {\n");
587 self.indent_level += 1;
588 code.push_str(&self.indent());
589 code.push_str(&format!(
590 "log::warn!(\"Function call to 0x{:08X} failed: {{:?}}\", e);\n",
591 target
592 ));
593 code.push_str(&self.indent());
594 code.push_str("ctx.lr = saved_lr; // Restore link register\n");
595 self.indent_level -= 1;
596 code.push_str(&self.indent());
597 code.push_str("}\n");
598 self.indent_level -= 1;
599 code.push_str(&self.indent());
600 code.push_str("}\n");
601 } else {
602 code.push_str(&self.indent());
603 code.push_str(&format!(
604 "ctx.pc = 0x{:08X}u32; // Unconditional branch\n",
605 target
606 ));
607 code.push_str(&self.indent());
608 code.push_str("return; // Branch out of function\n");
609 }
610 }
611 3..=5 => {
612 let bo = match &inst.instruction.operands[0] {
614 Operand::Condition(c) => *c,
615 _ => anyhow::bail!("First operand must be condition"),
616 };
617
618 let bi = if inst.instruction.operands.len() > 1 {
619 match &inst.instruction.operands[1] {
620 Operand::Condition(c) => *c,
621 _ => anyhow::bail!("Second operand must be condition"),
622 }
623 } else {
624 0
625 };
626
627 let target = if inst.instruction.operands.len() > 2 {
628 match &inst.instruction.operands[2] {
629 Operand::Immediate(bd) => *bd as i32,
630 Operand::Address(addr) => *addr as i32,
631 _ => 0,
632 }
633 } else {
634 0
635 };
636
637 let _label = self.next_label();
638 code.push_str(&self.indent());
639 code.push_str(&format!(
640 "let cr_bit = (ctx.get_cr_field({}) >> {}) & 1;\n",
641 bi / 4, bi % 4
642 ));
643 code.push_str(&self.indent());
644 code.push_str("if cr_bit != 0 {\n");
645 self.indent_level += 1;
646 code.push_str(&self.indent());
647 code.push_str(&format!(
648 "ctx.pc = ctx.pc + {}i32 as u32; // Conditional branch\n",
649 target
650 ));
651 code.push_str(&self.indent());
652 code.push_str("return; // Branch taken\n");
653 self.indent_level -= 1;
654 code.push_str(&self.indent());
655 code.push_str("}\n");
656 }
657 _ => {
658 code.push_str(&self.indent());
659 code.push_str("// Complex branch instruction\n");
660 }
661 }
662
663 Ok(code)
664 }
665
666 fn next_label(&mut self) -> String {
667 let label = format!("label_{}", self.label_counter);
668 self.label_counter += 1;
669 label
670 }
671
672 fn generate_compare(&mut self, inst: &DecodedInstruction) -> Result<String> {
673 let mut code = String::new();
674
675 if inst.instruction.operands.len() < 2 {
676 anyhow::bail!("Compare instruction requires at least 2 operands");
677 }
678
679 let bf = match &inst.instruction.operands[0] {
680 Operand::Condition(c) => *c,
681 _ => 0, };
683
684 let ra_reg = match &inst.instruction.operands[1] {
685 Operand::Register(r) => *r,
686 _ => anyhow::bail!("Second operand must be a register"),
687 };
688
689 let compare_value = if inst.instruction.operands.len() > 2 {
691 match &inst.instruction.operands[2] {
692 Operand::Register(rb) => {
693 format!("ctx.get_register({})", rb)
694 }
695 Operand::Immediate(i) => {
696 let val = *i as i32;
697 format!("{}i32", val)
698 }
699 _ => "0i32".to_string(),
700 }
701 } else {
702 "0i32".to_string()
703 };
704
705 let is_unsigned = inst.instruction.opcode == 10; code.push_str(&self.indent());
709 code.push_str(&format!(
710 "let ra_val = ctx.get_register({}) as {};\n",
711 ra_reg,
712 if is_unsigned { "u32" } else { "i32" }
713 ));
714 code.push_str(&self.indent());
715 code.push_str(&format!(
716 "let rb_val = {} as {};\n",
717 compare_value,
718 if is_unsigned { "u32" } else { "i32" }
719 ));
720
721 code.push_str(&self.indent());
723 code.push_str("let cr_field = if ra_val < rb_val {\n");
724 self.indent_level += 1;
725 code.push_str(&self.indent());
726 code.push_str("0x8u8 // Less than\n");
727 self.indent_level -= 1;
728 code.push_str(&self.indent());
729 code.push_str("} else if ra_val > rb_val {\n");
730 self.indent_level += 1;
731 code.push_str(&self.indent());
732 code.push_str("0x4u8 // Greater than\n");
733 self.indent_level -= 1;
734 code.push_str(&self.indent());
735 code.push_str("} else {\n");
736 self.indent_level += 1;
737 code.push_str(&self.indent());
738 code.push_str("0x2u8 // Equal\n");
739 self.indent_level -= 1;
740 code.push_str(&self.indent());
741 code.push_str("};\n");
742 code.push_str(&self.indent());
743 code.push_str(&format!("ctx.set_cr_field({}, cr_field);\n", bf));
744
745 Ok(code)
746 }
747
748 fn generate_move(&mut self, inst: &DecodedInstruction) -> Result<String> {
749 let mut code = String::new();
750
751 if inst.instruction.operands.is_empty() {
752 anyhow::bail!("Move instruction requires at least one operand");
753 }
754
755 if inst.instruction.operands.len() == 1 {
757 let reg = match &inst.instruction.operands[0] {
758 Operand::Register(r) => *r,
759 _ => anyhow::bail!("Move operand must be a register"),
760 };
761
762 code.push_str(&self.indent());
765 code.push_str(&format!(
766 "ctx.set_register({}, ctx.lr); // Move from/to link register\n",
767 reg
768 ));
769 }
770
771 Ok(code)
772 }
773
774 fn generate_floating_point(&mut self, inst: &DecodedInstruction) -> Result<String> {
775 let mut code = String::new();
776
777 if inst.instruction.operands.is_empty() {
778 anyhow::bail!("Floating point instruction requires operands");
779 }
780
781 match inst.instruction.operands.len() {
783 3 => {
784 let frt = match &inst.instruction.operands[0] {
786 Operand::FpRegister(r) => *r,
787 _ => anyhow::bail!("First operand must be FP register"),
788 };
789 let fra = match &inst.instruction.operands[1] {
790 Operand::FpRegister(r) => *r,
791 _ => anyhow::bail!("Second operand must be FP register"),
792 };
793 let frb = match &inst.instruction.operands[2] {
794 Operand::FpRegister(r) => *r,
795 _ => anyhow::bail!("Third operand must be FP register"),
796 };
797
798 let ext_opcode = (inst.raw >> 1) & 0x3FF;
800 let op = match ext_opcode {
801 21 => "+", 20 => "-", 25 => "*", 18 => "/", 14 => "+", 15 => "-", 28 => "-", 29 => "-", _ => "+", };
811
812 if ext_opcode == 14 || ext_opcode == 15 || ext_opcode == 28 || ext_opcode == 29 {
814 if inst.instruction.operands.len() >= 4 {
816 let frc = match &inst.instruction.operands[2] {
817 Operand::FpRegister(r) => *r,
818 _ => anyhow::bail!("Third operand must be FP register for multiply-add"),
819 };
820 code.push_str(&self.indent());
821 code.push_str(&format!(
822 "let mul_result = ctx.get_fpr({}) * ctx.get_fpr({});\n",
823 fra, frc
824 ));
825 code.push_str(&self.indent());
826 if ext_opcode == 28 || ext_opcode == 29 {
827 code.push_str("let mul_result = -mul_result;\n");
828 }
829 code.push_str(&self.indent());
830 code.push_str(&format!(
831 "let result = mul_result {} ctx.get_fpr({});\n",
832 if ext_opcode == 15 || ext_opcode == 29 { "-" } else { "+" },
833 frb
834 ));
835 if ext_opcode == 29 {
836 code.push_str(&self.indent());
837 code.push_str("let result = -result;\n");
838 }
839 } else {
840 anyhow::bail!("Multiply-add/subtract requires 4 operands");
841 }
842 } else {
843 code.push_str(&self.indent());
844 code.push_str(&format!(
845 "let result = ctx.get_fpr({}) {} ctx.get_fpr({});\n",
846 fra, op, frb
847 ));
848 }
849 code.push_str(&self.indent());
850 code.push_str(&format!("ctx.set_fpr({}, result);\n", frt));
851 }
852 2 => {
853 let frt = match &inst.instruction.operands[0] {
855 Operand::FpRegister(r) => *r,
856 _ => anyhow::bail!("First operand must be FP register"),
857 };
858 let ra = match &inst.instruction.operands[1] {
859 Operand::Register(r) => *r,
860 _ => anyhow::bail!("Second operand must be register"),
861 };
862
863 code.push_str(&self.indent());
864 code.push_str(&format!(
865 "let addr = ctx.get_register({}) as u32;\n",
866 ra
867 ));
868 code.push_str(&self.indent());
869 code.push_str("let value = f64::from_bits(memory.read_u64(addr).unwrap_or(0));\n");
870 code.push_str(&self.indent());
871 code.push_str(&format!("ctx.set_fpr({}, value);\n", frt));
872 }
873 _ => {
874 code.push_str(&self.indent());
875 code.push_str("// Complex floating point instruction\n");
876 }
877 }
878
879 Ok(code)
880 }
881
882 fn generate_condition_register(&mut self, inst: &DecodedInstruction) -> Result<String> {
883 let mut code = String::new();
884
885 if inst.instruction.operands.len() == 1 {
886 let reg = match &inst.instruction.operands[0] {
888 Operand::Register(r) => *r,
889 _ => anyhow::bail!("Operand must be register"),
890 };
891 code.push_str(&self.indent());
892 code.push_str(&format!(
893 "ctx.set_register({}, ctx.cr); // Move from/to condition register\n",
894 reg
895 ));
896 } else if inst.instruction.operands.len() == 3 {
897 let bt = match &inst.instruction.operands[0] {
899 Operand::Condition(c) => *c,
900 _ => anyhow::bail!("First operand must be condition"),
901 };
902 let ba = match &inst.instruction.operands[1] {
903 Operand::Condition(c) => *c,
904 _ => anyhow::bail!("Second operand must be condition"),
905 };
906 let bb = match &inst.instruction.operands[2] {
907 Operand::Condition(c) => *c,
908 _ => anyhow::bail!("Third operand must be condition"),
909 };
910
911 code.push_str(&self.indent());
912 code.push_str(&format!(
913 "let cr_a = ctx.get_cr_field({});\n",
914 ba / 4
915 ));
916 code.push_str(&self.indent());
917 code.push_str(&format!(
918 "let cr_b = ctx.get_cr_field({});\n",
919 bb / 4
920 ));
921 let ext_opcode = (inst.raw >> 1) & 0x3FF;
923 let cr_op = match ext_opcode {
924 257 => "&", 449 => "|", 193 => "^", 225 => "&", 33 => "|", 289 => "^", 129 => "&", 417 => "|", _ => "&", };
934
935 code.push_str(&self.indent());
936 if ext_opcode == 225 || ext_opcode == 33 || ext_opcode == 289 {
937 code.push_str(&format!(
939 "let cr_result = !(ctx.get_cr_field({}) {} ctx.get_cr_field({}));\n",
940 ba / 4, cr_op, bb / 4
941 ));
942 } else if ext_opcode == 129 {
943 code.push_str(&format!(
945 "let cr_result = ctx.get_cr_field({}) & !ctx.get_cr_field({});\n",
946 ba / 4, bb / 4
947 ));
948 } else if ext_opcode == 417 {
949 code.push_str(&format!(
951 "let cr_result = ctx.get_cr_field({}) | !ctx.get_cr_field({});\n",
952 ba / 4, bb / 4
953 ));
954 } else {
955 code.push_str(&format!(
956 "let cr_result = ctx.get_cr_field({}) {} ctx.get_cr_field({});\n",
957 ba / 4, cr_op, bb / 4
958 ));
959 }
960 code.push_str(&self.indent());
961 code.push_str(&format!(
962 "ctx.set_cr_field({}, cr_result);\n",
963 bt / 4
964 ));
965 }
966
967 Ok(code)
968 }
969
970 fn generate_shift(&mut self, inst: &DecodedInstruction) -> Result<String> {
971 let mut code = String::new();
972
973 if inst.instruction.operands.len() < 3 {
974 anyhow::bail!("Shift instruction requires at least 3 operands");
975 }
976
977 let rs = match &inst.instruction.operands[0] {
978 Operand::Register(r) => *r,
979 _ => anyhow::bail!("First operand must be register"),
980 };
981 let ra = match &inst.instruction.operands[1] {
982 Operand::Register(r) => *r,
983 _ => anyhow::bail!("Second operand must be register"),
984 };
985 let sh = match &inst.instruction.operands[2] {
986 Operand::ShiftAmount(s) => *s,
987 Operand::Register(r) => {
988 code.push_str(&self.indent());
990 code.push_str(&format!(
991 "let sh_amount = ctx.get_register({}) & 0x1F;\n",
992 r
993 ));
994 0 }
996 _ => anyhow::bail!("Third operand must be shift amount or register"),
997 };
998
999 code.push_str(&self.indent());
1001 if sh > 0 {
1002 code.push_str(&format!(
1003 "ctx.set_register({}, ctx.get_register({}) << {});\n",
1004 ra, rs, sh
1005 ));
1006 } else {
1007 code.push_str(&format!(
1008 "ctx.set_register({}, ctx.get_register({}) >> sh_amount);\n",
1009 ra, rs
1010 ));
1011 }
1012
1013 Ok(code)
1014 }
1015
1016 fn generate_rotate(&mut self, inst: &DecodedInstruction) -> Result<String> {
1017 let mut code = String::new();
1018
1019 if inst.instruction.operands.len() < 4 {
1020 anyhow::bail!("Rotate instruction requires 4 operands");
1021 }
1022
1023 let rs = match &inst.instruction.operands[0] {
1024 Operand::Register(r) => *r,
1025 _ => anyhow::bail!("First operand must be register"),
1026 };
1027 let ra = match &inst.instruction.operands[1] {
1028 Operand::Register(r) => *r,
1029 _ => anyhow::bail!("Second operand must be register"),
1030 };
1031 let sh = match &inst.instruction.operands[2] {
1032 Operand::ShiftAmount(s) => *s,
1033 _ => anyhow::bail!("Third operand must be shift amount"),
1034 };
1035 let mask = match &inst.instruction.operands[3] {
1036 Operand::Mask(m) => *m,
1037 _ => anyhow::bail!("Fourth operand must be mask"),
1038 };
1039
1040 code.push_str(&self.indent());
1041 code.push_str(&format!(
1042 "let rotated = ctx.get_register({}).rotate_left({} as u32);\n",
1043 rs, sh
1044 ));
1045 code.push_str(&self.indent());
1046 code.push_str(&format!(
1047 "let masked = rotated & 0x{:08X}u32;\n",
1048 mask
1049 ));
1050 code.push_str(&self.indent());
1051 code.push_str(&format!(
1052 "ctx.set_register({}, masked);\n",
1053 ra
1054 ));
1055
1056 Ok(code)
1057 }
1058
1059 fn generate_system(&mut self, inst: &DecodedInstruction) -> Result<String> {
1060 let mut code = String::new();
1061
1062 if !inst.instruction.operands.is_empty() {
1064 if let Operand::SpecialRegister(spr) = &inst.instruction.operands[0] {
1065 code.push_str(&self.indent());
1066 code.push_str(&format!(
1067 "// System register operation: SPR {}\n",
1068 spr
1069 ));
1070 if inst.instruction.operands.len() > 1 {
1071 if let Operand::Register(rt) = &inst.instruction.operands[1] {
1072 code.push_str(&self.indent());
1073 code.push_str(&format!(
1074 "// Move from/to SPR {} to/from r{}\n",
1075 spr, rt
1076 ));
1077 }
1078 }
1079 } else {
1080 code.push_str(&self.indent());
1081 code.push_str("// Cache control or memory synchronization\n");
1082 }
1083 } else {
1084 code.push_str(&self.indent());
1085 code.push_str(&format!("// System instruction: opcode 0x{:02X}\n", inst.instruction.opcode));
1086 code.push_str(&self.indent());
1087 code.push_str("// System instructions typically require special handling\n");
1088 }
1089
1090 Ok(code)
1091 }
1092
1093 fn generate_generic(&mut self, inst: &DecodedInstruction) -> Result<String> {
1094 let mut code = String::new();
1095 code.push_str(&self.indent());
1096 code.push_str(&format!("// Instruction type: {:?}, opcode: 0x{:02X}\n",
1097 inst.instruction.instruction_type, inst.instruction.opcode));
1098 code.push_str(&self.indent());
1099 code.push_str(&format!("// Raw: 0x{:08X}\n", inst.raw));
1100 code.push_str(&self.indent());
1101 code.push_str("// TODO: Implement proper handling for this instruction\n");
1102
1103 if !inst.instruction.operands.is_empty() {
1105 if let Operand::Register(rt) = &inst.instruction.operands[0] {
1106 code.push_str(&self.indent());
1107 code.push_str(&format!(
1108 "// First operand is register r{}\n",
1109 rt
1110 ));
1111 }
1112 }
1113
1114 Ok(code)
1115 }
1116
1117 fn type_to_rust(&self, ty: &crate::recompiler::analysis::TypeInfo) -> String {
1118 match ty {
1119 crate::recompiler::analysis::TypeInfo::Void => "()".to_string(),
1120 crate::recompiler::analysis::TypeInfo::Integer { signed, size } => {
1121 match (*signed, *size) {
1122 (true, 8) => "i8".to_string(),
1123 (false, 8) => "u8".to_string(),
1124 (true, 16) => "i16".to_string(),
1125 (false, 16) => "u16".to_string(),
1126 (true, 32) => "i32".to_string(),
1127 (false, 32) => "u32".to_string(),
1128 (true, 64) => "i64".to_string(),
1129 (false, 64) => "u64".to_string(),
1130 _ => "u32".to_string(),
1131 }
1132 }
1133 crate::recompiler::analysis::TypeInfo::Pointer { pointee } => {
1134 format!("*mut {}", self.type_to_rust(pointee))
1135 }
1136 _ => "u32".to_string(),
1137 }
1138 }
1139
1140 pub fn sanitize_identifier(&self, name: &str) -> String {
1141 name.replace(' ', "_")
1142 .replace('-', "_")
1143 .replace('.', "_")
1144 .chars()
1145 .filter(|c| c.is_alphanumeric() || *c == '_')
1146 .collect()
1147 }
1148
1149 fn indent(&self) -> String {
1150 " ".repeat(self.indent_level)
1151 }
1152}
1153
1154impl Default for CodeGenerator {
1155 fn default() -> Self {
1156 Self::new()
1157 }
1158}