@@ -6,7 +6,7 @@ use acvm::acir::circuit::BrilligOpcodeLocation;
6
6
use acvm:: brillig_vm:: brillig:: {
7
7
BinaryFieldOp , BinaryIntOp , BlackBoxOp , HeapArray , HeapVector , MemoryAddress , ValueOrArray ,
8
8
} ;
9
- use acvm:: { AcirField , FieldElement } ;
9
+ use acvm:: FieldElement ;
10
10
use noirc_errors:: debug_info:: DebugInfo ;
11
11
12
12
use crate :: bit_traits:: bits_needed_for;
@@ -674,45 +674,38 @@ fn handle_const(
674
674
) {
675
675
let tag = tag_from_bit_size ( * bit_size) ;
676
676
let dest = destination. to_usize ( ) as u32 ;
677
-
678
- if !matches ! ( tag, AvmTypeTag :: FIELD ) {
679
- avm_instrs. push ( generate_set_instruction ( tag, dest, value. to_u128 ( ) , indirect) ) ;
680
- } else {
681
- // We can't fit a field in an instruction. This should've been handled in Brillig.
682
- let field = value;
683
- if field. num_bits ( ) > 128 {
684
- panic ! ( "SET: Field value doesn't fit in 128 bits, that's not supported!" ) ;
685
- }
686
- avm_instrs. extend ( [
687
- generate_set_instruction ( AvmTypeTag :: UINT128 , dest, field. to_u128 ( ) , indirect) ,
688
- generate_cast_instruction ( dest, indirect, dest, indirect, AvmTypeTag :: FIELD ) ,
689
- ] ) ;
690
- }
677
+ avm_instrs. push ( generate_set_instruction ( tag, dest, value, indirect) ) ;
691
678
}
692
679
693
680
/// Generates an AVM SET instruction.
694
681
fn generate_set_instruction (
695
682
tag : AvmTypeTag ,
696
683
dest : u32 ,
697
- value : u128 ,
684
+ value : & FieldElement ,
698
685
indirect : bool ,
699
686
) -> AvmInstruction {
687
+ let bits_needed_val = bits_needed_for ( value) ;
688
+ let bits_needed_mem = if bits_needed_val >= 16 { 16 } else { bits_needed_for ( & dest) } ;
689
+ assert ! ( bits_needed_mem <= 16 ) ;
690
+ let bits_needed_opcode = bits_needed_val. max ( bits_needed_mem) ;
691
+
692
+ let set_opcode = match bits_needed_opcode {
693
+ 8 => AvmOpcode :: SET_8 ,
694
+ 16 => AvmOpcode :: SET_16 ,
695
+ 32 => AvmOpcode :: SET_32 ,
696
+ 64 => AvmOpcode :: SET_64 ,
697
+ 128 => AvmOpcode :: SET_128 ,
698
+ 254 => AvmOpcode :: SET_FF ,
699
+ _ => panic ! ( "Invalid bits needed for opcode: {}" , bits_needed_opcode) ,
700
+ } ;
701
+
700
702
AvmInstruction {
701
- opcode : AvmOpcode :: SET ,
703
+ opcode : set_opcode ,
702
704
indirect : if indirect { Some ( ZEROTH_OPERAND_INDIRECT ) } else { Some ( ALL_DIRECT ) } ,
703
705
tag : Some ( tag) ,
704
706
operands : vec ! [
705
- // const
706
- match tag {
707
- AvmTypeTag :: UINT8 => AvmOperand :: U8 { value: value as u8 } ,
708
- AvmTypeTag :: UINT16 => AvmOperand :: U16 { value: value as u16 } ,
709
- AvmTypeTag :: UINT32 => AvmOperand :: U32 { value: value as u32 } ,
710
- AvmTypeTag :: UINT64 => AvmOperand :: U64 { value: value as u64 } ,
711
- AvmTypeTag :: UINT128 => AvmOperand :: U128 { value } ,
712
- _ => panic!( "Invalid type tag {:?} for set" , tag) ,
713
- } ,
714
- // dest offset
715
- AvmOperand :: U32 { value: dest } ,
707
+ make_operand( bits_needed_opcode, value) ,
708
+ make_operand( bits_needed_mem, & dest) ,
716
709
] ,
717
710
}
718
711
}
@@ -1137,8 +1130,6 @@ pub fn map_brillig_pcs_to_avm_pcs(brillig_bytecode: &[BrilligOpcode<FieldElement
1137
1130
pc_map[ 0 ] = 0 ; // first PC is always 0 as there are no instructions inserted by AVM at start
1138
1131
for i in 0 ..brillig_bytecode. len ( ) - 1 {
1139
1132
let num_avm_instrs_for_this_brillig_instr = match & brillig_bytecode[ i] {
1140
- BrilligOpcode :: Const { bit_size : BitSize :: Field , .. } => 2 ,
1141
- BrilligOpcode :: IndirectConst { bit_size : BitSize :: Field , .. } => 2 ,
1142
1133
BrilligOpcode :: Cast { bit_size : BitSize :: Integer ( IntegerBitSize :: U1 ) , .. } => 3 ,
1143
1134
_ => 1 ,
1144
1135
} ;
0 commit comments