diff options
Diffstat (limited to 'ARMeilleure/Translation')
| -rw-r--r-- | ARMeilleure/Translation/RegisterUsage.cs | 37 | ||||
| -rw-r--r-- | ARMeilleure/Translation/RejitRequest.cs | 16 | ||||
| -rw-r--r-- | ARMeilleure/Translation/SsaConstruction.cs | 12 | ||||
| -rw-r--r-- | ARMeilleure/Translation/Translator.cs | 14 |
4 files changed, 55 insertions, 24 deletions
diff --git a/ARMeilleure/Translation/RegisterUsage.cs b/ARMeilleure/Translation/RegisterUsage.cs index becaa24c..84dfce7b 100644 --- a/ARMeilleure/Translation/RegisterUsage.cs +++ b/ARMeilleure/Translation/RegisterUsage.cs @@ -10,6 +10,7 @@ namespace ARMeilleure.Translation { private const long CallerSavedIntRegistersMask = 0x7fL << 9; private const long PStateNzcvFlagsMask = 0xfL << 60; + private const long FpStateNzcvFlagsMask = 0xfL << 60; private const long CallerSavedVecRegistersMask = 0xffffL << 16; @@ -68,7 +69,7 @@ namespace ARMeilleure.Translation } } - public static void RunPass(ControlFlowGraph cfg, bool isCompleteFunction) + public static void RunPass(ControlFlowGraph cfg, ExecutionMode mode, bool isCompleteFunction) { // Compute local register inputs and outputs used inside blocks. RegisterMask[] localInputs = new RegisterMask[cfg.Blocks.Count]; @@ -205,8 +206,8 @@ namespace ARMeilleure.Translation // It always needs a context load as it is the first block to run. if (block.Predecessors.Count == 0 || hasContextLoad) { - LoadLocals(block, globalInputs[block.Index].VecMask, RegisterType.Vector); - LoadLocals(block, globalInputs[block.Index].IntMask, RegisterType.Integer); + LoadLocals(block, globalInputs[block.Index].VecMask, RegisterType.Vector, mode); + LoadLocals(block, globalInputs[block.Index].IntMask, RegisterType.Integer, mode); } bool hasContextStore = HasContextStore(block); @@ -218,8 +219,8 @@ namespace ARMeilleure.Translation if (EndsWithReturn(block) || hasContextStore) { - StoreLocals(block, globalOutputs[block.Index].IntMask, RegisterType.Integer, isCompleteFunction); - StoreLocals(block, globalOutputs[block.Index].VecMask, RegisterType.Vector, isCompleteFunction); + StoreLocals(block, globalOutputs[block.Index].IntMask, RegisterType.Integer, mode, isCompleteFunction); + StoreLocals(block, globalOutputs[block.Index].VecMask, RegisterType.Vector, mode, isCompleteFunction); } } } @@ -263,6 +264,7 @@ namespace ARMeilleure.Translation { case RegisterType.Flag: intMask = (1L << RegsCount) << register.Index; break; case RegisterType.Integer: intMask = 1L << register.Index; break; + case RegisterType.FpFlag: vecMask = (1L << RegsCount) << register.Index; break; case RegisterType.Vector: vecMask = 1L << register.Index; break; } @@ -278,7 +280,7 @@ namespace ARMeilleure.Translation return oldValue != value; } - private static void LoadLocals(BasicBlock block, long inputs, RegisterType baseType) + private static void LoadLocals(BasicBlock block, long inputs, RegisterType baseType, ExecutionMode mode) { Operand arg0 = Local(OperandType.I64); @@ -291,7 +293,7 @@ namespace ARMeilleure.Translation continue; } - Operand dest = GetRegFromBit(bit, baseType); + Operand dest = GetRegFromBit(bit, baseType, mode); long offset = NativeContext.GetRegisterOffset(dest.GetRegister()); @@ -311,7 +313,7 @@ namespace ARMeilleure.Translation block.Operations.AddFirst(loadArg0); } - private static void StoreLocals(BasicBlock block, long outputs, RegisterType baseType, bool isCompleteFunction) + private static void StoreLocals(BasicBlock block, long outputs, RegisterType baseType, ExecutionMode mode, bool isCompleteFunction) { if (Optimizations.AssumeStrictAbiCompliance && isCompleteFunction) { @@ -319,7 +321,7 @@ namespace ARMeilleure.Translation { outputs = ClearCallerSavedIntRegs(outputs); } - else /* if (baseType == RegisterType.Vector) */ + else /* if (baseType == RegisterType.Vector || baseType == RegisterType.FpFlag) */ { outputs = ClearCallerSavedVecRegs(outputs); } @@ -340,7 +342,7 @@ namespace ARMeilleure.Translation continue; } - Operand source = GetRegFromBit(bit, baseType); + Operand source = GetRegFromBit(bit, baseType, mode); long offset = NativeContext.GetRegisterOffset(source.GetRegister()); @@ -356,28 +358,33 @@ namespace ARMeilleure.Translation } } - private static Operand GetRegFromBit(int bit, RegisterType baseType) + private static Operand GetRegFromBit(int bit, RegisterType baseType, ExecutionMode mode) { if (bit < RegsCount) { - return new Operand(bit, baseType, GetOperandType(baseType)); + return new Operand(bit, baseType, GetOperandType(baseType, mode)); } else if (baseType == RegisterType.Integer) { return new Operand(bit & RegsMask, RegisterType.Flag, OperandType.I32); } + else if (baseType == RegisterType.Vector) + { + return new Operand(bit & RegsMask, RegisterType.FpFlag, OperandType.I32); + } else { throw new ArgumentOutOfRangeException(nameof(bit)); } } - private static OperandType GetOperandType(RegisterType type) + private static OperandType GetOperandType(RegisterType type, ExecutionMode mode) { switch (type) { case RegisterType.Flag: return OperandType.I32; - case RegisterType.Integer: return OperandType.I64; + case RegisterType.FpFlag: return OperandType.I32; + case RegisterType.Integer: return (mode == ExecutionMode.Aarch64) ? OperandType.I64 : OperandType.I32; case RegisterType.Vector: return OperandType.V128; } @@ -405,7 +412,7 @@ namespace ARMeilleure.Translation private static long ClearCallerSavedVecRegs(long mask) { // TODO: ARM32 support. - mask &= ~CallerSavedVecRegistersMask; + mask &= ~(CallerSavedVecRegistersMask | FpStateNzcvFlagsMask); return mask; } diff --git a/ARMeilleure/Translation/RejitRequest.cs b/ARMeilleure/Translation/RejitRequest.cs new file mode 100644 index 00000000..e0b0e0b9 --- /dev/null +++ b/ARMeilleure/Translation/RejitRequest.cs @@ -0,0 +1,16 @@ +using ARMeilleure.State; + +namespace ARMeilleure.Translation +{ + struct RejitRequest + { + public ulong Address; + public ExecutionMode Mode; + + public RejitRequest(ulong address, ExecutionMode mode) + { + Address = address; + Mode = mode; + } + } +} diff --git a/ARMeilleure/Translation/SsaConstruction.cs b/ARMeilleure/Translation/SsaConstruction.cs index 292e74e3..46435f44 100644 --- a/ARMeilleure/Translation/SsaConstruction.cs +++ b/ARMeilleure/Translation/SsaConstruction.cs @@ -268,10 +268,14 @@ namespace ARMeilleure.Translation { return RegisterConsts.IntRegsCount + reg.Index; } - else /* if (reg.Type == RegisterType.Flag) */ + else if (reg.Type == RegisterType.Flag) { return RegisterConsts.IntAndVecRegsCount + reg.Index; } + else /* if (reg.Type == RegisterType.FpFlag) */ + { + return RegisterConsts.FpFlagsOffset + reg.Index; + } } private static Register GetRegisterFromId(int id) @@ -284,10 +288,14 @@ namespace ARMeilleure.Translation { return new Register(id - RegisterConsts.IntRegsCount, RegisterType.Vector); } - else /* if (id < RegisterConsts.TotalCount) */ + else if (id < RegisterConsts.FpFlagsOffset) { return new Register(id - RegisterConsts.IntAndVecRegsCount, RegisterType.Flag); } + else /* if (id < RegisterConsts.TotalCount) */ + { + return new Register(id - RegisterConsts.FpFlagsOffset, RegisterType.FpFlag); + } } } }
\ No newline at end of file diff --git a/ARMeilleure/Translation/Translator.cs b/ARMeilleure/Translation/Translator.cs index 4725ca59..3008303e 100644 --- a/ARMeilleure/Translation/Translator.cs +++ b/ARMeilleure/Translation/Translator.cs @@ -20,7 +20,7 @@ namespace ARMeilleure.Translation private ConcurrentDictionary<ulong, TranslatedFunction> _funcs; - private PriorityQueue<ulong> _backgroundQueue; + private PriorityQueue<RejitRequest> _backgroundQueue; private AutoResetEvent _backgroundTranslatorEvent; @@ -32,7 +32,7 @@ namespace ARMeilleure.Translation _funcs = new ConcurrentDictionary<ulong, TranslatedFunction>(); - _backgroundQueue = new PriorityQueue<ulong>(2); + _backgroundQueue = new PriorityQueue<RejitRequest>(2); _backgroundTranslatorEvent = new AutoResetEvent(false); } @@ -41,11 +41,11 @@ namespace ARMeilleure.Translation { while (_threadCount != 0) { - if (_backgroundQueue.TryDequeue(out ulong address)) + if (_backgroundQueue.TryDequeue(out RejitRequest request)) { - TranslatedFunction func = Translate(address, ExecutionMode.Aarch64, highCq: true); + TranslatedFunction func = Translate(request.Address, request.Mode, highCq: true); - _funcs.AddOrUpdate(address, func, (key, oldFunc) => func); + _funcs.AddOrUpdate(request.Address, func, (key, oldFunc) => func); } else { @@ -114,7 +114,7 @@ namespace ARMeilleure.Translation } else if (isCallTarget && func.ShouldRejit()) { - _backgroundQueue.Enqueue(0, address); + _backgroundQueue.Enqueue(0, new RejitRequest(address, mode)); _backgroundTranslatorEvent.Set(); } @@ -149,7 +149,7 @@ namespace ARMeilleure.Translation Logger.StartPass(PassName.RegisterUsage); - RegisterUsage.RunPass(cfg, isCompleteFunction: false); + RegisterUsage.RunPass(cfg, mode, isCompleteFunction: false); Logger.EndPass(PassName.RegisterUsage); |
