fn emit_mem_base(
    backend: &mut CodeGenerator,
    pv: &P<Value>,
    f_context: &mut FunctionContext,
    vm: &VM
) -> P<Value> {
    match pv.v {
        Value_::Memory(ref mem) => {
            let base = match mem {
                &MemoryLocation::VirtualAddress{ref base, ref offset, scale, signed} => {
                    if offset.is_some() {
                        let offset = offset.as_ref().unwrap();
                        if match_value_int_imm(offset) {
                            let offset_val = value_imm_to_i64(offset, signed) as i64;
                            if offset_val == 0 {
                                base.clone() // trivial
                            } else {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                emit_add_u64(backend, &temp, &base,
                                             (offset_val * scale as i64) as u64);
                                temp
                            }
                        } else {
                            let offset = emit_ireg_value(backend, offset, f_context, vm);

                            // TODO: If scale == r*m (for some 0 <= m <= 4), multiply offset by r
                            // then use and add_ext(,...,m)
                            if scale.is_power_of_two() &&
                                is_valid_immediate_extension(log2(scale)) {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                // temp = base + offset << log2(scale)
                                backend.emit_add_ext(&temp, &base, &offset, signed,
                                                     log2(scale) as u8);
                                temp
                            } else {
                                let temp_offset = make_temporary(f_context, offset.ty.clone(), vm);

                                // temp_offset = offset * scale
                                emit_mul_u64(backend, &temp_offset, &offset, scale);

                                // Don't need to create a new register, just overwrite temp_offset
                                let temp = cast_value(&temp_offset, &pv.ty);
                                // Need to use add_ext, in case offset is 32-bits
                                backend.emit_add_ext(&temp, &base, &temp_offset, signed, 0);
                                temp
                            }
                        }
                    }
                        else {
                            base.clone() // trivial
                        }
                }
                &MemoryLocation::Address{ref base, ref offset, shift, signed} => {
                    if offset.is_some() {
                        let ref offset = offset.as_ref().unwrap();

                        if match_value_int_imm(&offset) {
                            let offset = value_imm_to_u64(&offset);
                            if offset == 0 {
                                // Offset is 0, it can be ignored
                                base.clone()
                            } else {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                emit_add_u64(backend, &temp, &base, offset as u64);
                                temp
                            }
                        } else if RegGroup::get_from_value(&offset) == RegGroup::GPR &&
                            offset.is_reg() {
                            let temp = make_temporary(f_context, pv.ty.clone(), vm);
                            backend.emit_add_ext(&temp, &base, &offset, signed, shift);
                            temp
                        } else {
                            panic!("Offset should be an integer register or a constant")
                        }
                    } else {
                        // Simple base address
                        base.clone()
                    }
                }
                &MemoryLocation::Symbolic{..} => {
                    let temp = make_temporary(f_context, pv.ty.clone(), vm);
                    emit_addr_sym(backend, &temp, &pv, vm);
                    temp
                },
            };

            P(Value {
                hdr: MuEntityHeader::unnamed(vm.next_id()),
                ty: pv.ty.clone(),
                v: Value_::Memory(MemoryLocation::Address {
                    base: base.clone(),
                    offset: None,
                    shift: 0,
                    signed: false
                })
            })
        }
        _ => // Use the value as the base register
            {
                let tmp_mem = make_value_base_offset(&pv, 0, &pv.ty, vm);
                emit_mem_base(backend, &tmp_mem, f_context, vm)
            }
    }
}
// Same as emit_mem except returns a memory location with only a base
// NOTE: This code duplicates allot of code in emit_mem and emit_calculate_address
Same as emit_mem except returns a memory location with only a base
NOTE: This code duplicates allot of code in emit_mem and emit_calculate_address
Same as emit_mem except returns a memory location with only a base NOTE : This code duplicates allot of code in emit_mem and emit_calculate_address
fn emit_mem_base(
    backend: &mut CodeGenerator,
    pv: &P<Value>,
    f_context: &mut FunctionContext,
    vm: &VM
) -> P<Value> {
    match pv.v {
        Value_::Memory(ref mem) => {
            let base = match mem {
                &MemoryLocation::VirtualAddress{ref base, ref offset, scale, signed} => {
                    if offset.is_some() {
                        let offset = offset.as_ref().unwrap();
                        if match_value_int_imm(offset) {
                            let offset_val = value_imm_to_i64(offset, signed) as i64;
                            if offset_val == 0 {
                                base.clone() // trivial
                            } else {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                emit_add_u64(backend, &temp, &base,
                                             (offset_val * scale as i64) as u64);
                                temp
                            }
                        } else {
                            let offset = emit_ireg_value(backend, offset, f_context, vm);
                            // TODO: If scale == r*m (for some 0 <= m <= 4), multiply offset by r
                            // then use and add_ext(,...,m)
                            if scale.is_power_of_two() &&
                                is_valid_immediate_extension(log2(scale)) {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                // temp = base + offset << log2(scale)
                                backend.emit_add_ext(&temp, &base, &offset, signed,
                                                     log2(scale) as u8);
                                temp
                            } else {
                                let temp_offset = make_temporary(f_context, offset.ty.clone(), vm);
                                // temp_offset = offset * scale
                                emit_mul_u64(backend, &temp_offset, &offset, scale);
                                // Don't need to create a new register, just overwrite temp_offset
                                let temp = cast_value(&temp_offset, &pv.ty);
                                // Need to use add_ext, in case offset is 32-bits
                                backend.emit_add_ext(&temp, &base, &temp_offset, signed, 0);
                                temp
                            }
                        }
                    }
                        else {
                            base.clone() // trivial
                        }
                }
                &MemoryLocation::Address{ref base, ref offset, shift, signed} => {
                    if offset.is_some() {
                        let ref offset = offset.as_ref().unwrap();
                        if match_value_int_imm(&offset) {
                            let offset = value_imm_to_u64(&offset);
                            if offset == 0 {
                                // Offset is 0, it can be ignored
                                base.clone()
                            } else {
                                let temp = make_temporary(f_context, pv.ty.clone(), vm);
                                emit_add_u64(backend, &temp, &base, offset as u64);
                                temp
                            }
                        } else if RegGroup::get_from_value(&offset) == RegGroup::GPR &&
                            offset.is_reg() {
                            let temp = make_temporary(f_context, pv.ty.clone(), vm);
                            backend.emit_add_ext(&temp, &base, &offset, signed, shift);
                            temp
                        } else {
                            panic!("Offset should be an integer register or a constant")
                        }
                    } else {
                        // Simple base address
                        base.clone()
                    }
                }
                &MemoryLocation::Symbolic{..} => {
                    let temp = make_temporary(f_context, pv.ty.clone(), vm);
                    emit_addr_sym(backend, &temp, &pv, vm);
                    temp
                },
            };
            P(Value {
                hdr: MuEntityHeader::unnamed(vm.next_id()),
                ty: pv.ty.clone(),
                v: Value_::Memory(MemoryLocation::Address {
                    base: base.clone(),
                    offset: None,
                    shift: 0,
                    signed: false
                })
            })
        }
        _ => // Use the value as the base register
            {
                let tmp_mem = make_value_base_offset(&pv, 0, &pv.ty, vm);
                emit_mem_base(backend, &tmp_mem, f_context, vm)
            }
    }
}
fn emit_mem_base ( backend : & mut CodeGenerator , pv : & P < Value > , f_context : & mut FunctionContext , vm : & VM ) -> P < Value > { match pv . v { Value_ :: Memory ( ref mem ) => { let base = match mem { & MemoryLocation :: VirtualAddress { ref base , ref offset , scale , signed } => { if offset . is_some ( ) { let offset = offset . as_ref ( ) . unwrap ( ) ; if match_value_int_imm ( offset ) { let offset_val = value_imm_to_i64 ( offset , signed ) as i64 ; if offset_val == 0 { base . clone ( ) // trivial } else { let temp = make_temporary ( f_context , pv . ty . clone ( ) , vm ) ; emit_add_u64 ( backend , & temp , & base , ( offset_val * scale as i64 ) as u64 ) ; temp } } else { let offset = emit_ireg_value ( backend , offset , f_context , vm ) ; // TODO: If scale == r*m (for some 0 <= m <= 4), multiply offset by r // then use and add_ext(,...,m) if scale . is_power_of_two ( ) && is_valid_immediate_extension ( log2 ( scale ) ) { let temp = make_temporary ( f_context , pv . ty . clone ( ) , vm ) ; // temp = base + offset << log2(scale) backend . emit_add_ext ( & temp , & base , & offset , signed , log2 ( scale ) as u8 ) ; temp } else { let temp_offset = make_temporary ( f_context , offset . ty . clone ( ) , vm ) ; // temp_offset = offset * scale emit_mul_u64 ( backend , & temp_offset , & offset , scale ) ; // Don't need to create a new register, just overwrite temp_offset let temp = cast_value ( & temp_offset , & pv . ty ) ; // Need to use add_ext, in case offset is 32-bits backend . emit_add_ext ( & temp , & base , & temp_offset , signed , 0 ) ; temp } } } else { base . clone ( ) // trivial } } & MemoryLocation :: Address { ref base , ref offset , shift , signed } => { if offset . is_some ( ) { let ref offset = offset . as_ref ( ) . unwrap ( ) ; if match_value_int_imm ( & offset ) { let offset = value_imm_to_u64 ( & offset ) ; if offset == 0 { // Offset is 0, it can be ignored base . clone ( ) } else { let temp = make_temporary ( f_context , pv . ty . clone ( ) , vm ) ; emit_add_u64 ( backend , & temp , & base , offset as u64 ) ; temp } } else if RegGroup :: get_from_value ( & offset ) == RegGroup :: GPR && offset . is_reg ( ) { let temp = make_temporary ( f_context , pv . ty . clone ( ) , vm ) ; backend . emit_add_ext ( & temp , & base , & offset , signed , shift ) ; temp } else { panic ! ( " " ) } } else { // Simple base address base . clone ( ) } } & MemoryLocation :: Symbolic { .. } => { let temp = make_temporary ( f_context , pv . ty . clone ( ) , vm ) ; emit_addr_sym ( backend , & temp , & pv , vm ) ; temp } , } ; P ( Value { hdr : MuEntityHeader :: unnamed ( vm . next_id ( ) ) , ty : pv . ty . clone ( ) , v : Value_ :: Memory ( MemoryLocation :: Address { base : base . clone ( ) , offset : None , shift : 0 , signed : false } ) } ) } _ => // Use the value as the base register { let tmp_mem = make_value_base_offset ( & pv , 0 , & pv . ty , vm ) ; emit_mem_base ( backend , & tmp_mem , f_context , vm ) } } }
Same as emit_mem except returns a memory location with only a base
NOTE: This code duplicates allot of code in emit_mem and emit_calculate_address
Same as emit_mem except returns a memory location with only a base NOTE : This code duplicates allot of code in emit_mem and emit_calculate_address
backend
&mut CodeGenerator
pv
&P<Value>
f_context
&mut FunctionContext
vm
&VM
backend
&mut CodeGenerator
pv
&P<Value>
f_context
&mut FunctionContext
vm
&VM