protected void EmitDictionaryLookup(NodeFactory factory, ref ARMEmitter encoder, Register context, Register result, GenericLookupResult lookup, bool relocsOnly)
        {
            // INVARIANT: must not trash context register

            // Find the generic dictionary slot
            int dictionarySlot = 0;

            if (!relocsOnly)
            {
                // The concrete slot won't be known until we're emitting data - don't ask for it in relocsOnly.
                dictionarySlot = factory.GenericDictionaryLayout(_dictionaryOwner).GetSlotForEntry(lookup);
            }

            // Load the generic dictionary cell
            encoder.EmitLDR(result, context, ((short)(dictionarySlot * factory.Target.PointerSize)));

            switch (lookup.LookupResultReferenceType(factory))
            {
            case GenericLookupResultReferenceType.Indirect:
                // Do another indirection
                encoder.EmitLDR(result, result);
                break;

            case GenericLookupResultReferenceType.ConditionalIndirect:
                // Test result, 0x1
                // JEQ L1
                // mov result, [result-1]
                // L1:
                throw new NotImplementedException();

            default:
                break;
            }
        }
예제 #2
0
        protected void EmitDictionaryLookup(NodeFactory factory, ref X64Emitter encoder, Register context, Register result, GenericLookupResult lookup, bool relocsOnly)
        {
            // INVARIANT: must not trash context register

            // Find the generic dictionary slot
            int dictionarySlot = 0;

            if (!relocsOnly)
            {
                // The concrete slot won't be known until we're emitting data - don't ask for it in relocsOnly.
                dictionarySlot = factory.GenericDictionaryLayout(_dictionaryOwner).GetSlotForEntry(lookup);
            }

            // Load the generic dictionary cell
            AddrMode loadEntry = new AddrMode(
                context, null, dictionarySlot * factory.Target.PointerSize, 0, AddrModeSize.Int64);

            encoder.EmitMOV(result, ref loadEntry);

            // If there's any invalid entries, we need to test for them
            //
            // Only do this in relocsOnly to make it easier to weed out bugs - the _hasInvalidEntries
            // flag can change over the course of compilation and the bad slot helper dependency
            // should be reported by someone else - the system should not rely on it coming from here.
            if (!relocsOnly && _hasInvalidEntries)
            {
                encoder.EmitCompareToZero(result);
                encoder.EmitJE(GetBadSlotHelper(factory));
            }

            switch (lookup.LookupResultReferenceType(factory))
            {
            case GenericLookupResultReferenceType.Indirect:
                // Do another indirection
                loadEntry = new AddrMode(result, null, 0, 0, AddrModeSize.Int64);
                encoder.EmitMOV(result, ref loadEntry);
                break;

            case GenericLookupResultReferenceType.ConditionalIndirect:
                // Test result, 0x1
                // JEQ L1
                // mov result, [result-1]
                // L1:
                throw new NotImplementedException();

            default:
                break;
            }
        }