fn memory_location_shift(
    backend: &mut CodeGenerator,
    mem: MemoryLocation,
    more_offset: i64,
    f_context: &mut FunctionContext,
    vm: &VM
) -> MemoryLocation {
    if more_offset == 0 {
        return mem; // No need to do anything
    }
    match mem {
        MemoryLocation::VirtualAddress {
            ref base,
            ref offset,
            scale,
            signed
        } => {
            let mut new_scale = 1;
            let new_offset = if offset.is_some() {
                let offset = offset.as_ref().unwrap();
                if match_value_int_imm(&offset) {
                    let offset = offset.extract_int_const().unwrap() * scale + (more_offset as u64);
                    make_value_int_const(offset as u64, vm)
                } else {
                    let offset = emit_ireg_value(backend, &offset, f_context, vm);
                    let temp = make_temporary(f_context, offset.ty.clone(), vm);

                    if more_offset % (scale as i64) == 0 {
                        // temp = offset + more_offset/scale
                        emit_add_u64(
                            backend,
                            &temp,
                            &offset,
                            (more_offset / (scale as i64)) as u64
                        );
                        new_scale = scale;
                    } else {
                        // temp = offset*scale + more_offset
                        emit_mul_u64(backend, &temp, &offset, scale);
                        emit_add_u64(backend, &temp, &temp, more_offset as u64);
                    }

                    temp
                }
            } else {
                make_value_int_const(more_offset as u64, vm)
            };

            // if offset was an immediate or more_offset % scale != 0:
            //      new_offset = offset*scale+more_offset
            //      new_scale = 1
            // otherwise:
            //      new_offset = offset + more_offset/scale
            //      new_scale = scale
            // Either way: (new_offset*new_scale) = offset*scale+more_offset
            MemoryLocation::VirtualAddress {
                base: base.clone(),
                offset: Some(new_offset),
                scale: new_scale,
                signed: signed
            }
        }
        _ => panic!("expected a VirtualAddress memory location")
    }
}
// Returns a memory location that points to 'Base + offset*scale + more_offset'
Returns a memory location that points to 'Base + offset*scale + more_offset'
Returns a memory location that points to ' Base + offset * scale + more_offset '
fn memory_location_shift(
    backend: &mut CodeGenerator,
    mem: MemoryLocation,
    more_offset: i64,
    f_context: &mut FunctionContext,
    vm: &VM
) -> MemoryLocation {
    if more_offset == 0 {
        return mem; // No need to do anything
    }
    match mem {
        MemoryLocation::VirtualAddress {
            ref base,
            ref offset,
            scale,
            signed
        } => {
            let mut new_scale = 1;
            let new_offset = if offset.is_some() {
                let offset = offset.as_ref().unwrap();
                if match_value_int_imm(&offset) {
                    let offset = offset.extract_int_const().unwrap() * scale + (more_offset as u64);
                    make_value_int_const(offset as u64, vm)
                } else {
                    let offset = emit_ireg_value(backend, &offset, f_context, vm);
                    let temp = make_temporary(f_context, offset.ty.clone(), vm);
                    if more_offset % (scale as i64) == 0 {
                        // temp = offset + more_offset/scale
                        emit_add_u64(
                            backend,
                            &temp,
                            &offset,
                            (more_offset / (scale as i64)) as u64
                        );
                        new_scale = scale;
                    } else {
                        // temp = offset*scale + more_offset
                        emit_mul_u64(backend, &temp, &offset, scale);
                        emit_add_u64(backend, &temp, &temp, more_offset as u64);
                    }
                    temp
                }
            } else {
                make_value_int_const(more_offset as u64, vm)
            };
            // if offset was an immediate or more_offset % scale != 0:
            //      new_offset = offset*scale+more_offset
            //      new_scale = 1
            // otherwise:
            //      new_offset = offset + more_offset/scale
            //      new_scale = scale
            // Either way: (new_offset*new_scale) = offset*scale+more_offset
            MemoryLocation::VirtualAddress {
                base: base.clone(),
                offset: Some(new_offset),
                scale: new_scale,
                signed: signed
            }
        }
        _ => panic!("expected a VirtualAddress memory location")
    }
}
fn memory_location_shift ( backend : & mut CodeGenerator , mem : MemoryLocation , more_offset : i64 , f_context : & mut FunctionContext , vm : & VM ) -> MemoryLocation { if more_offset == 0 { return mem ; // No need to do anything } match mem { MemoryLocation :: VirtualAddress { ref base , ref offset , scale , signed } => { let mut new_scale = 1 ; let new_offset = if offset . is_some ( ) { let offset = offset . as_ref ( ) . unwrap ( ) ; if match_value_int_imm ( & offset ) { let offset = offset . extract_int_const ( ) . unwrap ( ) * scale + ( more_offset as u64 ) ; make_value_int_const ( offset as u64 , vm ) } else { let offset = emit_ireg_value ( backend , & offset , f_context , vm ) ; let temp = make_temporary ( f_context , offset . ty . clone ( ) , vm ) ; if more_offset % ( scale as i64 ) == 0 { // temp = offset + more_offset/scale emit_add_u64 ( backend , & temp , & offset , ( more_offset / ( scale as i64 ) ) as u64 ) ; new_scale = scale ; } else { // temp = offset*scale + more_offset emit_mul_u64 ( backend , & temp , & offset , scale ) ; emit_add_u64 ( backend , & temp , & temp , more_offset as u64 ) ; } temp } } else { make_value_int_const ( more_offset as u64 , vm ) } ; // if offset was an immediate or more_offset % scale != 0: //      new_offset = offset*scale+more_offset //      new_scale = 1 // otherwise: //      new_offset = offset + more_offset/scale //      new_scale = scale // Either way: (new_offset*new_scale) = offset*scale+more_offset MemoryLocation :: VirtualAddress { base : base . clone ( ) , offset : Some ( new_offset ) , scale : new_scale , signed : signed } } _ => panic ! ( " " ) } }
Returns a memory location that points to 'Base + offset*scale + more_offset'
Returns a memory location that points to ' Base + offset * scale + more_offset '
backend
&mut CodeGenerator
mem
MemoryLocation
more_offset
i64
f_context
&mut FunctionContext
vm
&VM
backend
&mut CodeGenerator
mem
MemoryLocation
more_offset
i64
f_context
&mut FunctionContext
vm
&VM