@@ -36,7 +36,11 @@ static uint32_t intern_constant(bal_translation_context_t *, bal_constant_t);
3636static void translate_const (bal_translation_context_t * ,
3737 const bal_decoder_instruction_metadata_t * ,
3838 const uint32_t * );
39+ static void translate_sub (bal_translation_context_t * ,
40+ const bal_decoder_instruction_metadata_t * ,
41+ const uint32_t * );
3942static void translate_return (bal_translation_context_t * , const uint32_t * );
43+
4044BAL_COLD bal_error_t
4145bal_engine_init (const bal_allocator_t * allocator , bal_engine_t * engine , bal_logger_t logger )
4246{
@@ -146,9 +150,11 @@ bal_engine_translate(bal_engine_t *BAL_RESTRICT engine,
146150 return engine -> status ;
147151 }
148152
149- if (BAL_UNLIKELY (NULL == & guest_address_start ))
153+ if (BAL_UNLIKELY (NULL == guest_address_start ))
150154 {
151- BAL_LOG_INFO (& engine -> logger , "Guest Address is NULL, assuming entry point is 0x0" );
155+ BAL_LOG_ERROR (& engine -> logger , "Guest Address is NULL, aborting translation" );
156+ engine -> status = BAL_ERROR_INVALID_ARGUMENT ;
157+ return engine -> status ;
152158 }
153159
154160 const size_t max_instructions_size_bytes = max_instructions * ARM_INSTRUCTION_SIZE_BYTES ;
@@ -262,6 +268,9 @@ bal_engine_translate(bal_engine_t *BAL_RESTRICT engine,
262268 case OPCODE_CONST :
263269 translate_const (& context , metadata , arm_instruction_operands );
264270 break ;
271+ case OPCODE_SUB :
272+ translate_sub (& context , metadata , arm_instruction_operands );
273+ break ;
265274 case OPCODE_RETURN :
266275 translate_return (& context , arm_instruction_operands );
267276 is_block_terminated = true;
@@ -574,4 +583,74 @@ translate_return(bal_translation_context_t *context, const uint32_t *arm_registe
574583 BAL_LOG_DEBUG (
575584 context -> logger , " EMIT: v%u = RET v%u" , context -> instruction_count , rn_ssa_index );
576585 context -> instruction_count ++ ;
586+ }
587+
588+ BAL_HOT static void
589+ translate_sub (bal_translation_context_t * context ,
590+ const bal_decoder_instruction_metadata_t * metadata ,
591+ const uint32_t * arm_registers )
592+ {
593+ if (BAL_UNLIKELY (BAL_OPERAND_TYPE_IMMEDIATE != metadata -> operands [2 ].type ))
594+ {
595+ BAL_LOG_DEBUG (context -> logger ,
596+ " SKIPPED: SUB variant '%s' not yet implemented in IR layer." ,
597+ metadata -> name );
598+ return ;
599+ }
600+
601+ const uint64_t rd = arm_registers [0 ];
602+ const uint64_t rn = arm_registers [1 ];
603+ const uint64_t imm12 = arm_registers [2 ];
604+ const uint64_t sh = arm_registers [3 ];
605+ const uint64_t shift = (1 == sh ) ? 12 : 0 ;
606+ const uint64_t value = imm12 << shift ;
607+
608+ BAL_LOG_TRACE (context -> logger ,
609+ " Variant='Imm' Rd=%lu Rn=%lu Imm12=0x%lX Shift=%lu Value=0x%llX" ,
610+ rd ,
611+ rn ,
612+ imm12 ,
613+ shift ,
614+ (unsigned long long )value );
615+
616+ const uint64_t rn_ssa_index = get_or_create_ssa_index (context , rn );
617+ const uint64_t value_const_index = intern_constant (context , value );
618+
619+ if (BAL_UNLIKELY (context -> status != BAL_SUCCESS ))
620+ {
621+ return ;
622+ }
623+
624+ bal_bit_width_t bit_width ;
625+
626+ switch (metadata -> operands [0 ].type )
627+ {
628+ case BAL_OPERAND_TYPE_REGISTER_32 :
629+ bit_width = 32 ;
630+ break ;
631+ case BAL_OPERAND_TYPE_REGISTER_64 :
632+ bit_width = 64 ;
633+ break ;
634+ default :
635+ BAL_LOG_ERROR (context -> logger , "Unknown register type for SUB (Imm) Rd register" );
636+ context -> status = BAL_ERROR_INCORRECT_REGISTER_TYPE ;
637+ return ;
638+ }
639+
640+ * context -> ir_instruction_cursor = (bal_instruction_t )OPCODE_SUB << BAL_OPCODE_SHIFT_POSITION
641+ | rn_ssa_index << BAL_SOURCE1_SHIFT_POSITION
642+ | value_const_index << BAL_SOURCE2_SHIFT_POSITION ;
643+ * context -> bit_width_cursor = bit_width ;
644+
645+ BAL_LOG_DEBUG (context -> logger ,
646+ " EMIT: v%u = SUB v%u, c%u (%u-bit)" ,
647+ context -> instruction_count ,
648+ (uint32_t )rn_ssa_index ,
649+ (uint32_t )(value_const_index & ~BAL_IS_CONSTANT_BIT_POSITION ),
650+ bit_width );
651+
652+ context -> source_variables [rd ].current_ssa_index = context -> instruction_count ;
653+ BAL_LOG_TRACE (context -> logger , " SSA UPDATE: X%lu -> v%u" , rd , context -> instruction_count );
654+
655+ context -> instruction_count ++ ;
577656}
0 commit comments