Refactor NCE

This commit mainly just refactors NCE by adding spacing and fixing other minor errors. In addition, it adds comments to `nce/guest.h` and `nce/instructions.h`.
This commit is contained in:
◱ PixelyIon 2020-03-25 01:50:28 +05:30 committed by ◱ PixelyIon
parent 42d982c6fb
commit bbdd41a86c
6 changed files with 310 additions and 133 deletions

View File

@ -947,7 +947,10 @@
<inspection_tool class="GroovyAccessToStaticFieldLockedOnInstance" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyAccessToStaticFieldLockedOnInstance" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyAccessibility" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyAccessibility" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyAssignabilityCheck" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyAssignabilityCheck" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyAssignmentCanBeOperatorAssignment" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyAssignmentCanBeOperatorAssignment" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreLazyOperators" value="true" />
<option name="ignoreObscureOperators" value="false" />
</inspection_tool>
<inspection_tool class="GroovyAssignmentToForLoopParameter" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyAssignmentToForLoopParameter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyAssignmentToMethodParameter" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyAssignmentToMethodParameter" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyBreak" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyBreak" enabled="false" level="WARNING" enabled_by_default="false" />
@ -958,13 +961,19 @@
<inspection_tool class="GroovyConditionalWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyConditionalWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyConstantConditional" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyConstantConditional" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyConstantIfStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyConstantIfStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyConstantNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyConstantNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_regex" value="[A-Z\d]*" />
<option name="m_minLength" value="4" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovyConstructorNamedArguments" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyConstructorNamedArguments" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyContinue" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyContinue" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyContinueOrBreakFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyContinueOrBreakFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyDivideByZero" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyDivideByZero" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyDocCheck" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="GroovyDocCheck" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="GroovyDoubleCheckedLocking" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyDoubleCheckedLocking" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreOnVolatileVariables" value="false" />
</inspection_tool>
<inspection_tool class="GroovyDoubleNegation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyDoubleNegation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyDuplicateSwitchBranch" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyDuplicateSwitchBranch" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyEmptyCatchBlock" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyEmptyCatchBlock" enabled="false" level="WARNING" enabled_by_default="false" />
@ -975,12 +984,22 @@
<inspection_tool class="GroovyFallthrough" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyFallthrough" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyGStringKey" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyGStringKey" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyIfStatementWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyIfStatementWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyIfStatementWithTooManyBranches" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyIfStatementWithTooManyBranches" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="3" />
</inspection_tool>
<inspection_tool class="GroovyInArgumentCheck" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyInArgumentCheck" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyInfiniteLoopStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyInfiniteLoopStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyInfiniteRecursion" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyInfiniteRecursion" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyInstanceMethodNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyInstanceMethodNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<inspection_tool class="GroovyInstanceVariableNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> <option name="m_regex" value="[a-z][A-Za-z\d]*" />
<option name="m_minLength" value="4" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovyInstanceVariableNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_regex" value="m_[a-z][A-Za-z\d]*" />
<option name="m_minLength" value="1" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovyLabeledStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyLabeledStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyListGetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyListGetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyListSetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyListSetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" />
@ -992,10 +1011,14 @@
<inspection_tool class="GroovyLoopStatementThatDoesntLoop" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyLoopStatementThatDoesntLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyMapGetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyMapGetCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyMapPutCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyMapPutCanBeKeyedAccess" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyMethodParameterCount" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyMethodParameterCount" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="5" />
</inspection_tool>
<inspection_tool class="GroovyMethodWithMoreThanThreeNegations" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyMethodWithMoreThanThreeNegations" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyMissingReturnStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyMissingReturnStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyMultipleReturnPointsPerMethod" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyMultipleReturnPointsPerMethod" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="1" />
</inspection_tool>
<inspection_tool class="GroovyNegatedConditional" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyNegatedConditional" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyNegatedIf" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyNegatedIf" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyNestedAssignment" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyNestedAssignment" enabled="false" level="WARNING" enabled_by_default="false" />
@ -1005,12 +1028,26 @@
<inspection_tool class="GroovyNonShortCircuitBoolean" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyNonShortCircuitBoolean" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyNotifyWhileNotSynchronized" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyNotifyWhileNotSynchronized" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyOctalInteger" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyOctalInteger" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyOverlyComplexArithmeticExpression" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyOverlyComplexArithmeticExpression" enabled="false" level="WARNING" enabled_by_default="false">
<inspection_tool class="GroovyOverlyComplexBooleanExpression" enabled="false" level="WARNING" enabled_by_default="false" /> <option name="m_limit" value="3" />
<inspection_tool class="GroovyOverlyComplexMethod" enabled="false" level="WARNING" enabled_by_default="false" /> </inspection_tool>
<inspection_tool class="GroovyOverlyLongMethod" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyOverlyComplexBooleanExpression" enabled="false" level="WARNING" enabled_by_default="false">
<inspection_tool class="GroovyOverlyNestedMethod" enabled="false" level="WARNING" enabled_by_default="false" /> <option name="m_limit" value="3" />
<inspection_tool class="GroovyParameterNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> </inspection_tool>
<inspection_tool class="GroovyOverlyComplexMethod" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="10" />
</inspection_tool>
<inspection_tool class="GroovyOverlyLongMethod" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="30" />
</inspection_tool>
<inspection_tool class="GroovyOverlyNestedMethod" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_limit" value="5" />
</inspection_tool>
<inspection_tool class="GroovyParameterNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_regex" value="[a-z][A-Za-z\d]*" />
<option name="m_minLength" value="4" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovyPointlessArithmetic" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyPointlessArithmetic" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyPointlessBoolean" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyPointlessBoolean" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyPublicFieldAccessedInSynchronizedContext" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyPublicFieldAccessedInSynchronizedContext" enabled="false" level="WARNING" enabled_by_default="false" />
@ -1021,8 +1058,16 @@
<inspection_tool class="GroovyReturnFromClosureCanBeImplicit" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyReturnFromClosureCanBeImplicit" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyReturnFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyReturnFromFinallyBlock" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovySillyAssignment" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovySillyAssignment" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyStaticMethodNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyStaticMethodNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<inspection_tool class="GroovyStaticVariableNamingConvention" enabled="false" level="WARNING" enabled_by_default="false" /> <option name="m_regex" value="[a-z][A-Za-z\d]*" />
<option name="m_minLength" value="4" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovyStaticVariableNamingConvention" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_regex" value="s_[a-z][A-Za-z\d]*" />
<option name="m_minLength" value="4" />
<option name="m_maxLength" value="32" />
</inspection_tool>
<inspection_tool class="GroovySwitchStatementWithNoDefault" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovySwitchStatementWithNoDefault" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovySynchronizationOnNonFinalField" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovySynchronizationOnNonFinalField" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovySynchronizationOnThis" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovySynchronizationOnThis" enabled="false" level="WARNING" enabled_by_default="false" />
@ -1048,10 +1093,25 @@
<inspection_tool class="GroovyVariableNotAssigned" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="GroovyVariableNotAssigned" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="GroovyWaitCallNotInLoop" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyWaitCallNotInLoop" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyWaitWhileNotSynchronized" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyWaitWhileNotSynchronized" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="GroovyWhileLoopSpinsOnField" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="GroovyWhileLoopSpinsOnField" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreNonEmtpyLoops" value="false" />
</inspection_tool>
<inspection_tool class="Guava" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="Guava" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="HardCodedStringLiteral" enabled="false" level="WARNING" enabled_by_default="false">
<inspection_tool class="HardcodedFileSeparators" enabled="false" level="WARNING" enabled_by_default="false" /> <option name="ignoreForAssertStatements" value="true" />
<option name="ignoreForExceptionConstructors" value="true" />
<option name="ignoreForSpecifiedExceptionConstructors" value="" />
<option name="ignoreForJUnitAsserts" value="true" />
<option name="ignoreForClassReferences" value="true" />
<option name="ignoreForPropertyKeyReferences" value="true" />
<option name="ignoreForNonAlpha" value="true" />
<option name="ignoreAssignedToConstants" value="false" />
<option name="ignoreToString" value="false" />
<option name="nonNlsCommentPattern" value="NON-NLS" />
</inspection_tool>
<inspection_tool class="HardcodedFileSeparators" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_recognizeExampleMediaType" value="false" />
</inspection_tool>
<inspection_tool class="HardcodedLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HardcodedLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="HasPlatformType" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="HasPlatformType" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="HashCodeUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="HashCodeUsesNonFinalVariable" enabled="true" level="WARNING" enabled_by_default="true" />
@ -1146,7 +1206,7 @@
<inspection_tool class="IncrementDecrementUsedAsExpression" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="IncrementDecrementUsedAsExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="IndexOfReplaceableByContains" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InfiniteLoopStatement" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InfiniteLoopStatement" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="InfiniteRecursion" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="InfiniteRecursion" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="InitializationIssue" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="InitializationIssue" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="InitializerIssues" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="InitializerIssues" enabled="true" level="ERROR" enabled_by_default="true" />
<inspection_tool class="InjectedReferences" enabled="true" level="ERROR" enabled_by_default="true" /> <inspection_tool class="InjectedReferences" enabled="true" level="ERROR" enabled_by_default="true" />
@ -1584,7 +1644,7 @@
<inspection_tool class="NumericToString" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="NumericToString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OCDFA" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCDFA" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OCGlobalUnused" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCGlobalUnused" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OCInconsistentNaming" enabled="false" level="WEAK WARNING" enabled_by_default="false" /> <inspection_tool class="OCInconsistentNaming" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="OCLegacyObjCLiteral" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCLegacyObjCLiteral" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OCLoopDoesntUseConditionVariable" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCLoopDoesntUseConditionVariable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="OCNotLocalizedString" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="OCNotLocalizedString" enabled="true" level="WARNING" enabled_by_default="true" />
@ -1783,7 +1843,16 @@
<inspection_tool class="PyClassHasNoInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="PyClassHasNoInitInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyClassicStyleClassInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="PyClassicStyleClassInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyComparisonWithNoneInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="PyComparisonWithNoneInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PyCompatibilityInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="PyCompatibilityInspection" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ourVersions">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="2.7" />
<item index="1" class="java.lang.String" itemvalue="3.8" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyDataclassInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyDataclassInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyDecoratorInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyDecoratorInspection" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyDefaultArgumentInspection" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="PyDefaultArgumentInspection" enabled="true" level="WARNING" enabled_by_default="true" />
@ -1874,7 +1943,7 @@
<inspection_tool class="RecursivePropertyAccessor" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RecursivePropertyAccessor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantArrayCreation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantArrayCreation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantAsync" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantAsync" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantCast" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantCast" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="RedundantClassCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantClassCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantCollectionOperation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantCollectionOperation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantCompanionReference" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="RedundantCompanionReference" enabled="true" level="WARNING" enabled_by_default="true" />
@ -2081,8 +2150,8 @@
<inspection_tool class="SortModifiers" enabled="true" level="WEAK WARNING" enabled_by_default="true" /> <inspection_tool class="SortModifiers" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SortedCollectionWithNonComparableKeys" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="SortedCollectionWithNonComparableKeys" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true"> <inspection_tool class="SpellCheckingInspection" enabled="true" level="TYPO" enabled_by_default="true">
<option name="processCode" value="true" /> <option name="processCode" value="false" />
<option name="processLiterals" value="true" /> <option name="processLiterals" value="false" />
<option name="processComments" value="true" /> <option name="processComments" value="true" />
</inspection_tool> </inspection_tool>
<inspection_tool class="StandardVariableNames" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StandardVariableNames" enabled="true" level="WARNING" enabled_by_default="true" />
@ -2112,7 +2181,15 @@
<inspection_tool class="StringBufferReplaceableByString" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringBufferReplaceableByString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringBufferReplaceableByStringBuilder" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringBufferReplaceableByStringBuilder" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringBufferToStringInConcatenation" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringBufferToStringInConcatenation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenation" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="StringConcatenation" enabled="false" level="WARNING" enabled_by_default="false">
<option name="ignoreAsserts" value="false" />
<option name="ignoreSystemOuts" value="false" />
<option name="ignoreSystemErrs" value="false" />
<option name="ignoreThrowableArguments" value="false" />
<option name="ignoreConstantInitializers" value="false" />
<option name="ignoreInTestCode" value="false" />
<option name="ignoreInToString" value="false" />
</inspection_tool>
<inspection_tool class="StringConcatenationArgumentToLogCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationArgumentToLogCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationInFormatCall" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationInFormatCall" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringConcatenationInLoops" enabled="true" level="WARNING" enabled_by_default="true" /> <inspection_tool class="StringConcatenationInLoops" enabled="true" level="WARNING" enabled_by_default="true" />
@ -2465,5 +2542,17 @@
</value> </value>
</option> </option>
</inspection_tool> </inspection_tool>
<inspection_tool class="unused" enabled="false" level="WARNING" enabled_by_default="false">
<option name="LOCAL_VARIABLE" value="true" />
<option name="FIELD" value="true" />
<option name="METHOD" value="true" />
<option name="CLASS" value="true" />
<option name="PARAMETER" value="true" />
<option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
<option name="ADD_MAINS_TO_ENTRIES" value="true" />
<option name="ADD_APPLET_TO_ENTRIES" value="true" />
<option name="ADD_SERVLET_TO_ENTRIES" value="true" />
<option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
</inspection_tool>
</profile> </profile>
</component> </component>

View File

@ -7,7 +7,7 @@
bool Halt; bool Halt;
jobject Surface; jobject Surface;
uint FaultCount; uint FaultCount;
skyline::GroupMutex jniMtx; skyline::GroupMutex JniMtx;
void signalHandler(int signal) { void signalHandler(int signal) {
syslog(LOG_ERR, "Halting program due to signal: %s", strsignal(signal)); syslog(LOG_ERR, "Halting program due to signal: %s", strsignal(signal));
@ -56,18 +56,18 @@ extern "C" JNIEXPORT void Java_emu_skyline_GameActivity_executeRom(JNIEnv *env,
} }
extern "C" JNIEXPORT void Java_emu_skyline_GameActivity_setHalt(JNIEnv *env, jobject instance, jboolean halt) { extern "C" JNIEXPORT void Java_emu_skyline_GameActivity_setHalt(JNIEnv *env, jobject instance, jboolean halt) {
jniMtx.lock(skyline::GroupMutex::Group::Group2); JniMtx.lock(skyline::GroupMutex::Group::Group2);
Halt = halt; Halt = halt;
jniMtx.unlock(); JniMtx.unlock();
} }
extern "C" JNIEXPORT void Java_emu_skyline_GameActivity_setSurface(JNIEnv *env, jobject instance, jobject surface) { extern "C" JNIEXPORT void Java_emu_skyline_GameActivity_setSurface(JNIEnv *env, jobject instance, jobject surface) {
jniMtx.lock(skyline::GroupMutex::Group::Group2); JniMtx.lock(skyline::GroupMutex::Group::Group2);
if (!env->IsSameObject(Surface, nullptr)) if (!env->IsSameObject(Surface, nullptr))
env->DeleteGlobalRef(Surface); env->DeleteGlobalRef(Surface);
if (!env->IsSameObject(surface, nullptr)) if (!env->IsSameObject(surface, nullptr))
Surface = env->NewGlobalRef(surface); Surface = env->NewGlobalRef(surface);
else else
Surface = surface; Surface = surface;
jniMtx.unlock(); JniMtx.unlock();
} }

View File

@ -3,32 +3,38 @@
#include "os.h" #include "os.h"
#include "jvm.h" #include "jvm.h"
#include "nce/guest.h" #include "nce/guest.h"
#include "nce/instr.h" #include "nce/instructions.h"
#include "kernel/svc.h" #include "kernel/svc.h"
#include "nce.h" #include "nce.h"
extern bool Halt; extern bool Halt;
extern jobject Surface; extern jobject Surface;
extern skyline::GroupMutex jniMtx; extern skyline::GroupMutex JniMtx;
namespace skyline { namespace skyline {
void NCE::KernelThread(pid_t thread) { void NCE::KernelThread(pid_t thread) {
try { try {
state.thread = state.process->threads.at(thread); state.thread = state.process->threads.at(thread);
state.ctx = reinterpret_cast<ThreadContext *>(state.thread->ctxMemory->kernel.address); state.ctx = reinterpret_cast<ThreadContext *>(state.thread->ctxMemory->kernel.address);
while (true) { while (true) {
asm("yield"); asm("yield");
if (__predict_false(Halt)) if (__predict_false(Halt))
break; break;
if (__predict_false(!Surface)) if (__predict_false(!Surface))
continue; continue;
if (state.ctx->state == ThreadState::WaitKernel) { if (state.ctx->state == ThreadState::WaitKernel) {
std::lock_guard jniGd(jniMtx); std::lock_guard jniGd(JniMtx);
if (__predict_false(Halt)) if (__predict_false(Halt))
break; break;
if (__predict_false(!Surface)) if (__predict_false(!Surface))
continue; continue;
const u16 svc = static_cast<const u16>(state.ctx->commandId); const u16 svc = static_cast<const u16>(state.ctx->commandId);
try { try {
if (kernel::svc::SvcTable[svc]) { if (kernel::svc::SvcTable[svc]) {
state.logger->Debug("SVC called 0x{:X}", svc); state.logger->Debug("SVC called 0x{:X}", svc);
@ -39,10 +45,12 @@ namespace skyline {
} catch (const std::exception &e) { } catch (const std::exception &e) {
throw exception("{} (SVC: 0x{:X})", e.what(), svc); throw exception("{} (SVC: 0x{:X})", e.what(), svc);
} }
state.ctx->state = ThreadState::WaitRun; state.ctx->state = ThreadState::WaitRun;
} else if (__predict_false(state.ctx->state == ThreadState::GuestCrash)) { } else if (__predict_false(state.ctx->state == ThreadState::GuestCrash)) {
state.logger->Warn("Thread with PID {} has crashed due to signal: {}", thread, strsignal(state.ctx->commandId)); state.logger->Warn("Thread with PID {} has crashed due to signal: {}", thread, strsignal(state.ctx->commandId));
ThreadTrace(); ThreadTrace();
state.ctx->state = ThreadState::WaitRun; state.ctx->state = ThreadState::WaitRun;
break; break;
} }
@ -52,12 +60,15 @@ namespace skyline {
} catch (...) { } catch (...) {
state.logger->Error("An unknown exception has occurred"); state.logger->Error("An unknown exception has occurred");
} }
if (!Halt) { if (!Halt) {
if (thread == state.process->pid) { if (thread == state.process->pid) {
jniMtx.lock(GroupMutex::Group::Group2); JniMtx.lock(GroupMutex::Group::Group2);
state.os->KillThread(thread); state.os->KillThread(thread);
Halt = true; Halt = true;
jniMtx.unlock();
JniMtx.unlock();
} else { } else {
state.os->KillThread(thread); state.os->KillThread(thread);
} }
@ -74,9 +85,11 @@ namespace skyline {
void NCE::Execute() { void NCE::Execute() {
try { try {
while (true) { while (true) {
std::lock_guard guard(jniMtx); std::lock_guard guard(JniMtx);
if (Halt) if (Halt)
break; break;
state.gpu->Loop(); state.gpu->Loop();
} }
} catch (const std::exception &e) { } catch (const std::exception &e) {
@ -84,10 +97,11 @@ namespace skyline {
} catch (...) { } catch (...) {
state.logger->Error("An unknown exception has occurred"); state.logger->Error("An unknown exception has occurred");
} }
if (!Halt) { if (!Halt) {
jniMtx.lock(GroupMutex::Group::Group2); JniMtx.lock(GroupMutex::Group::Group2);
Halt = true; Halt = true;
jniMtx.unlock(); JniMtx.unlock();
} }
} }
@ -100,10 +114,14 @@ namespace skyline {
void ExecuteFunctionCtx(ThreadCall call, Registers &funcRegs, ThreadContext *ctx) __attribute__ ((optnone)) { void ExecuteFunctionCtx(ThreadCall call, Registers &funcRegs, ThreadContext *ctx) __attribute__ ((optnone)) {
ctx->commandId = static_cast<u32>(call); ctx->commandId = static_cast<u32>(call);
Registers registers = ctx->registers; Registers registers = ctx->registers;
while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel); while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel);
ctx->registers = funcRegs; ctx->registers = funcRegs;
ctx->state = ThreadState::WaitFunc; ctx->state = ThreadState::WaitFunc;
while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel); while (ctx->state != ThreadState::WaitInit && ctx->state != ThreadState::WaitKernel);
funcRegs = ctx->registers; funcRegs = ctx->registers;
ctx->registers = registers; ctx->registers = registers;
} }
@ -115,6 +133,7 @@ namespace skyline {
void NCE::ExecuteFunction(ThreadCall call, Registers &funcRegs) { void NCE::ExecuteFunction(ThreadCall call, Registers &funcRegs) {
if (state.process->status == kernel::type::KProcess::Status::Exiting) if (state.process->status == kernel::type::KProcess::Status::Exiting)
throw exception("Executing function on Exiting process"); throw exception("Executing function on Exiting process");
auto thread = state.thread ? state.thread : state.process->threads.at(state.process->pid); auto thread = state.thread ? state.thread : state.process->threads.at(state.process->pid);
ExecuteFunctionCtx(call, funcRegs, reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address)); ExecuteFunctionCtx(call, funcRegs, reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address));
} }
@ -127,10 +146,12 @@ namespace skyline {
void NCE::StartThread(u64 entryArg, u32 handle, std::shared_ptr<kernel::type::KThread> &thread) { void NCE::StartThread(u64 entryArg, u32 handle, std::shared_ptr<kernel::type::KThread> &thread) {
auto ctx = reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address); auto ctx = reinterpret_cast<ThreadContext *>(thread->ctxMemory->kernel.address);
while (ctx->state != ThreadState::WaitInit); while (ctx->state != ThreadState::WaitInit);
ctx->tpidrroEl0 = thread->tls; ctx->tpidrroEl0 = thread->tls;
ctx->registers.x0 = entryArg; ctx->registers.x0 = entryArg;
ctx->registers.x1 = handle; ctx->registers.x1 = handle;
ctx->state = ThreadState::WaitRun; ctx->state = ThreadState::WaitRun;
state.logger->Debug("Starting kernel thread for guest thread: {}", thread->pid); state.logger->Debug("Starting kernel thread for guest thread: {}", thread->pid);
threadMap[thread->pid] = std::make_shared<std::thread>(&NCE::KernelThread, this, thread->pid); threadMap[thread->pid] = std::make_shared<std::thread>(&NCE::KernelThread, this, thread->pid);
} }
@ -139,30 +160,40 @@ namespace skyline {
std::string raw; std::string raw;
std::string trace; std::string trace;
std::string regStr; std::string regStr;
ctx = ctx ? ctx : state.ctx; ctx = ctx ? ctx : state.ctx;
if (numHist) { if (numHist) {
std::vector<u32> instrs(numHist); std::vector<u32> instrs(numHist);
u64 size = sizeof(u32) * numHist; u64 size = sizeof(u32) * numHist;
u64 offset = ctx->pc - size + (2 * sizeof(u32)); u64 offset = ctx->pc - size + (2 * sizeof(u32));
state.process->ReadMemory(instrs.data(), offset, size); state.process->ReadMemory(instrs.data(), offset, size);
for (auto &instr : instrs) { for (auto &instr : instrs) {
instr = __builtin_bswap32(instr); instr = __builtin_bswap32(instr);
if (offset == ctx->pc) if (offset == ctx->pc)
trace += fmt::format("\n-> 0x{:X} : 0x{:08X}", offset, instr); trace += fmt::format("\n-> 0x{:X} : 0x{:08X}", offset, instr);
else else
trace += fmt::format("\n 0x{:X} : 0x{:08X}", offset, instr); trace += fmt::format("\n 0x{:X} : 0x{:08X}", offset, instr);
raw += fmt::format("{:08X}", instr); raw += fmt::format("{:08X}", instr);
offset += sizeof(u32); offset += sizeof(u32);
} }
} }
if (ctx->faultAddress) if (ctx->faultAddress)
regStr += fmt::format("\nFault Address: 0x{:X}", ctx->faultAddress); regStr += fmt::format("\nFault Address: 0x{:X}", ctx->faultAddress);
if (ctx->sp) if (ctx->sp)
regStr += fmt::format("\nStack Pointer: 0x{:X}", ctx->sp); regStr += fmt::format("\nStack Pointer: 0x{:X}", ctx->sp);
for (u16 index = 0; index < constant::NumRegs - 1; index += 2) { for (u16 index = 0; index < constant::NumRegs - 1; index += 2) {
auto xStr = index < 10 ? " X" : "X"; auto xStr = index < 10 ? " X" : "X";
regStr += fmt::format("\n{}{}: 0x{:<16X} {}{}: 0x{:X}", xStr, index, ctx->registers.regs[index], xStr, index + 1, ctx->registers.regs[index + 1]); regStr += fmt::format("\n{}{}: 0x{:<16X} {}{}: 0x{:X}", xStr, index, ctx->registers.regs[index], xStr, index + 1, ctx->registers.regs[index + 1]);
} }
if (numHist) { if (numHist) {
state.logger->Debug("Process Trace:{}", trace); state.logger->Debug("Process Trace:{}", trace);
state.logger->Debug("Raw Instructions: 0x{}", raw); state.logger->Debug("Raw Instructions: 0x{}", raw);
@ -197,7 +228,7 @@ namespace skyline {
auto instrMrs = reinterpret_cast<instr::Mrs *>(address); auto instrMrs = reinterpret_cast<instr::Mrs *>(address);
if (instrSvc->Verify()) { if (instrSvc->Verify()) {
instr::B bjunc(offset); instr::B bJunc(offset);
constexpr u32 strLr = 0xF81F0FFE; // STR LR, [SP, #-16]! constexpr u32 strLr = 0xF81F0FFE; // STR LR, [SP, #-16]!
offset += sizeof(strLr); offset += sizeof(strLr);
instr::BL bSvCtx(patchOffset - offset); instr::BL bSvCtx(patchOffset - offset);
@ -217,7 +248,7 @@ namespace skyline {
instr::B bret(-offset + sizeof(u32)); instr::B bret(-offset + sizeof(u32));
offset += sizeof(bret); offset += sizeof(bret);
*address = bjunc.raw; *address = bJunc.raw;
patch.push_back(strLr); patch.push_back(strLr);
patch.push_back(bSvCtx.raw); patch.push_back(bSvCtx.raw);
for (auto &instr : movPc) for (auto &instr : movPc)
@ -229,7 +260,7 @@ namespace skyline {
patch.push_back(bret.raw); patch.push_back(bret.raw);
} else if (instrMrs->Verify()) { } else if (instrMrs->Verify()) {
if (instrMrs->srcReg == constant::TpidrroEl0) { if (instrMrs->srcReg == constant::TpidrroEl0) {
instr::B bjunc(offset); instr::B bJunc(offset);
u32 strX0{}; u32 strX0{};
if (instrMrs->destReg != regs::X0) { if (instrMrs->destReg != regs::X0) {
strX0 = 0xF81F0FE0; // STR X0, [SP, #-16]! strX0 = 0xF81F0FE0; // STR X0, [SP, #-16]!
@ -250,7 +281,7 @@ namespace skyline {
instr::B bret(-offset + sizeof(u32)); instr::B bret(-offset + sizeof(u32));
offset += sizeof(bret); offset += sizeof(bret);
*address = bjunc.raw; *address = bJunc.raw;
if (strX0) if (strX0)
patch.push_back(strX0); patch.push_back(strX0);
patch.push_back(mrsX0); patch.push_back(mrsX0);
@ -262,7 +293,7 @@ namespace skyline {
patch.push_back(bret.raw); patch.push_back(bret.raw);
} else if (frequency != constant::TegraX1Freq) { } else if (frequency != constant::TegraX1Freq) {
if (instrMrs->srcReg == constant::CntpctEl0) { if (instrMrs->srcReg == constant::CntpctEl0) {
instr::B bjunc(offset); instr::B bJunc(offset);
offset += guest::rescaleClockSize; offset += guest::rescaleClockSize;
instr::Ldr ldr(0xF94003E0); // LDR XOUT, [SP] instr::Ldr ldr(0xF94003E0); // LDR XOUT, [SP]
ldr.destReg = instrMrs->destReg; ldr.destReg = instrMrs->destReg;
@ -272,7 +303,7 @@ namespace skyline {
instr::B bret(-offset + sizeof(u32)); instr::B bret(-offset + sizeof(u32));
offset += sizeof(bret); offset += sizeof(bret);
*address = bjunc.raw; *address = bJunc.raw;
auto size = patch.size(); auto size = patch.size();
patch.resize(size + (guest::rescaleClockSize / sizeof(u32))); patch.resize(size + (guest::rescaleClockSize / sizeof(u32)));
std::memcpy(patch.data() + size, reinterpret_cast<void *>(&guest::RescaleClock), guest::rescaleClockSize); std::memcpy(patch.data() + size, reinterpret_cast<void *>(&guest::RescaleClock), guest::rescaleClockSize);
@ -280,13 +311,13 @@ namespace skyline {
patch.push_back(addSp); patch.push_back(addSp);
patch.push_back(bret.raw); patch.push_back(bret.raw);
} else if (instrMrs->srcReg == constant::CntfrqEl0) { } else if (instrMrs->srcReg == constant::CntfrqEl0) {
instr::B bjunc(offset); instr::B bJunc(offset);
auto movFreq = instr::MoveU32Reg(static_cast<regs::X>(instrMrs->destReg), constant::TegraX1Freq); auto movFreq = instr::MoveU32Reg(static_cast<regs::X>(instrMrs->destReg), constant::TegraX1Freq);
offset += sizeof(u32) * movFreq.size(); offset += sizeof(u32) * movFreq.size();
instr::B bret(-offset + sizeof(u32)); instr::B bret(-offset + sizeof(u32));
offset += sizeof(bret); offset += sizeof(bret);
*address = bjunc.raw; *address = bJunc.raw;
for (auto &instr : movFreq) for (auto &instr : movFreq)
patch.push_back(instr); patch.push_back(instr);
patch.push_back(bret.raw); patch.push_back(bret.raw);
@ -298,6 +329,7 @@ namespace skyline {
} }
} }
} }
offset -= sizeof(u32); offset -= sizeof(u32);
patchOffset -= sizeof(u32); patchOffset -= sizeof(u32);
} }

View File

@ -1,7 +1,7 @@
#include <asm/siginfo.h>
#include <csignal> #include <csignal>
#include <cstdlib> #include <cstdlib>
#include <initializer_list> // This is used implicitly #include <initializer_list> // This is used implicitly
#include <asm/siginfo.h>
#include "guest_common.h" #include "guest_common.h"
#define FORCE_INLINE __attribute__((always_inline)) inline // NOLINT(cppcoreguidelines-macro-usage) #define FORCE_INLINE __attribute__((always_inline)) inline // NOLINT(cppcoreguidelines-macro-usage)
@ -98,8 +98,10 @@ namespace skyline::guest {
void SvcHandler(u64 pc, u32 svc) { void SvcHandler(u64 pc, u32 svc) {
volatile ThreadContext *ctx; volatile ThreadContext *ctx;
asm("MRS %0, TPIDR_EL0":"=r"(ctx)); asm("MRS %0, TPIDR_EL0":"=r"(ctx));
ctx->pc = pc; ctx->pc = pc;
ctx->commandId = svc; ctx->commandId = svc;
if (svc == 0xB) { // svcSleepThread if (svc == 0xB) { // svcSleepThread
switch (ctx->registers.x0) { switch (ctx->registers.x0) {
case 0: case 0:
@ -119,6 +121,7 @@ namespace skyline::guest {
"LDR LR, [SP], #16":: : "x0", "x1", "x2", "x3", "x4", "x5", "x8"); "LDR LR, [SP], #16":: : "x0", "x1", "x2", "x3", "x4", "x5", "x8");
break; break;
} }
default: { default: {
struct timespec spec = { struct timespec spec = {
.tv_sec = static_cast<time_t>(ctx->registers.x0 / 1000000000), .tv_sec = static_cast<time_t>(ctx->registers.x0 / 1000000000),
@ -160,20 +163,25 @@ namespace skyline::guest {
"LDP X1, X2, [SP], #16"::"r"(ctx->registers.x0)); "LDP X1, X2, [SP], #16"::"r"(ctx->registers.x0));
return; return;
} }
while (true) { while (true) {
ctx->state = ThreadState::WaitKernel; ctx->state = ThreadState::WaitKernel;
while (ctx->state == ThreadState::WaitKernel); while (ctx->state == ThreadState::WaitKernel);
if (ctx->state == ThreadState::WaitRun) { if (ctx->state == ThreadState::WaitRun) {
break; break;
} else if (ctx->state == ThreadState::WaitFunc) { } else if (ctx->state == ThreadState::WaitFunc) {
if (ctx->commandId == static_cast<u32>(ThreadCall::Syscall)) { if (ctx->commandId == static_cast<u32>(ThreadCall::Syscall)) {
SaveCtxStack(); SaveCtxStack();
LoadCtxTls(); LoadCtxTls();
asm("STR LR, [SP, #-16]!\n\t" asm("STR LR, [SP, #-16]!\n\t"
"MOV LR, SP\n\t" "MOV LR, SP\n\t"
"SVC #0\n\t" "SVC #0\n\t"
"MOV SP, LR\n\t" "MOV SP, LR\n\t"
"LDR LR, [SP], #16"); "LDR LR, [SP], #16");
SaveCtxTls(); SaveCtxTls();
LoadCtxStack(); LoadCtxStack();
} else if (ctx->commandId == static_cast<u32>(ThreadCall::Memcopy)) { } else if (ctx->commandId == static_cast<u32>(ThreadCall::Memcopy)) {
@ -181,11 +189,13 @@ namespace skyline::guest {
auto dest = reinterpret_cast<u8 *>(ctx->registers.x1); auto dest = reinterpret_cast<u8 *>(ctx->registers.x1);
auto size = ctx->registers.x2; auto size = ctx->registers.x2;
auto end = src + size; auto end = src + size;
while (src < end) while (src < end)
*(src++) = *(dest++); *(src++) = *(dest++);
} else if (ctx->commandId == static_cast<u32>(ThreadCall::Clone)) { } else if (ctx->commandId == static_cast<u32>(ThreadCall::Clone)) {
SaveCtxStack(); SaveCtxStack();
LoadCtxTls(); LoadCtxTls();
asm("STR LR, [SP, #-16]!\n\t" asm("STR LR, [SP, #-16]!\n\t"
"MOV LR, SP\n\t" "MOV LR, SP\n\t"
"SVC #0\n\t" "SVC #0\n\t"
@ -225,25 +235,31 @@ namespace skyline::guest {
".parent:\n\t" ".parent:\n\t"
"MOV SP, LR\n\t" "MOV SP, LR\n\t"
"LDR LR, [SP], #16"); "LDR LR, [SP], #16");
SaveCtxTls(); SaveCtxTls();
LoadCtxStack(); LoadCtxStack();
} }
} }
} }
ctx->state = ThreadState::Running; ctx->state = ThreadState::Running;
} }
void SignalHandler(int signal, siginfo_t *info, ucontext_t *ucontext) { void SignalHandler(int signal, siginfo_t *info, ucontext_t *ucontext) {
volatile ThreadContext *ctx; volatile ThreadContext *ctx;
asm("MRS %0, TPIDR_EL0":"=r"(ctx)); asm("MRS %0, TPIDR_EL0":"=r"(ctx));
for (u8 index = 0; index < 30; index++) for (u8 index = 0; index < 30; index++)
ctx->registers.regs[index] = ucontext->uc_mcontext.regs[index]; ctx->registers.regs[index] = ucontext->uc_mcontext.regs[index];
ctx->pc = ucontext->uc_mcontext.pc; ctx->pc = ucontext->uc_mcontext.pc;
ctx->commandId = static_cast<u32>(signal); ctx->commandId = static_cast<u32>(signal);
ctx->faultAddress = ucontext->uc_mcontext.fault_address; ctx->faultAddress = ucontext->uc_mcontext.fault_address;
ctx->sp = ucontext->uc_mcontext.sp; ctx->sp = ucontext->uc_mcontext.sp;
while (true) { while (true) {
ctx->state = ThreadState::GuestCrash; ctx->state = ThreadState::GuestCrash;
if (ctx->state == ThreadState::WaitRun) if (ctx->state == ThreadState::WaitRun)
exit(0); exit(0);
} }
@ -252,20 +268,24 @@ namespace skyline::guest {
void GuestEntry(u64 address) { void GuestEntry(u64 address) {
volatile ThreadContext *ctx; volatile ThreadContext *ctx;
asm("MRS %0, TPIDR_EL0":"=r"(ctx)); asm("MRS %0, TPIDR_EL0":"=r"(ctx));
while (true) { while (true) {
ctx->state = ThreadState::WaitInit; ctx->state = ThreadState::WaitInit;
while (ctx->state == ThreadState::WaitInit); while (ctx->state == ThreadState::WaitInit);
if (ctx->state == ThreadState::WaitRun) { if (ctx->state == ThreadState::WaitRun) {
break; break;
} else if (ctx->state == ThreadState::WaitFunc) { } else if (ctx->state == ThreadState::WaitFunc) {
if (ctx->commandId == static_cast<u32>(ThreadCall::Syscall)) { if (ctx->commandId == static_cast<u32>(ThreadCall::Syscall)) {
SaveCtxStack(); SaveCtxStack();
LoadCtxTls(); LoadCtxTls();
asm("STR LR, [SP, #-16]!\n\t" asm("STR LR, [SP, #-16]!\n\t"
"MOV LR, SP\n\t" "MOV LR, SP\n\t"
"SVC #0\n\t" "SVC #0\n\t"
"MOV SP, LR\n\t" "MOV SP, LR\n\t"
"LDR LR, [SP], #16"); "LDR LR, [SP], #16");
SaveCtxTls(); SaveCtxTls();
LoadCtxStack(); LoadCtxStack();
} }
@ -274,17 +294,22 @@ namespace skyline::guest {
auto dest = reinterpret_cast<u8 *>(ctx->registers.x1); auto dest = reinterpret_cast<u8 *>(ctx->registers.x1);
auto size = ctx->registers.x2; auto size = ctx->registers.x2;
auto end = src + size; auto end = src + size;
while (src < end) while (src < end)
*(src++) = *(dest++); *(src++) = *(dest++);
} }
} }
struct sigaction sigact{ struct sigaction sigact{
.sa_sigaction = reinterpret_cast<void (*)(int, struct siginfo *, void *)>(reinterpret_cast<void *>(SignalHandler)), .sa_sigaction = reinterpret_cast<void (*)(int, struct siginfo *, void *)>(reinterpret_cast<void *>(SignalHandler)),
.sa_flags = SA_SIGINFO, .sa_flags = SA_SIGINFO,
}; };
for (int signal : {SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV}) for (int signal : {SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV})
sigaction(signal, &sigact, nullptr); sigaction(signal, &sigact, nullptr);
ctx->state = ThreadState::Running; ctx->state = ThreadState::Running;
asm("MOV LR, %0\n\t" asm("MOV LR, %0\n\t"
"MOV X0, %1\n\t" "MOV X0, %1\n\t"
"MOV X1, %2\n\t" "MOV X1, %2\n\t"
@ -317,6 +342,7 @@ namespace skyline::guest {
"MOV X28, XZR\n\t" "MOV X28, XZR\n\t"
"MOV X29, XZR\n\t" "MOV X29, XZR\n\t"
"RET"::"r"(address), "r"(ctx->registers.x0), "r"(ctx->registers.x1) : "x0", "x1", "lr"); "RET"::"r"(address), "r"(ctx->registers.x0), "r"(ctx->registers.x1) : "x0", "x1", "lr");
__builtin_unreachable(); __builtin_unreachable();
} }
} }

View File

@ -2,21 +2,41 @@
namespace skyline { namespace skyline {
namespace guest { namespace guest {
constexpr size_t saveCtxSize = 20 * sizeof(u32); constexpr size_t saveCtxSize = 20 * sizeof(u32); //!< The size of the SaveCtx function in 32-bit ARMv8 instructions
constexpr size_t loadCtxSize = 20 * sizeof(u32); constexpr size_t loadCtxSize = 20 * sizeof(u32); //!< The size of the LoadCtx function in 32-bit ARMv8 instructions
constexpr size_t rescaleClockSize = 16 * sizeof(u32); constexpr size_t rescaleClockSize = 16 * sizeof(u32); //!< The size of the RescaleClock function in 32-bit ARMv8 instructions
#ifdef NDEBUG #ifdef NDEBUG
constexpr size_t svcHandlerSize = 225 * sizeof(u32); constexpr size_t svcHandlerSize = 225 * sizeof(u32); //!< The size of the SvcHandler (Release) function in 32-bit ARMv8 instructions
#else #else
constexpr size_t svcHandlerSize = 400 * sizeof(u32); constexpr size_t svcHandlerSize = 400 * sizeof(u32); //!< The size of the SvcHandler (Debug) function in 32-bit ARMv8 instructions
#endif #endif
/**
* @brief This is the entry point for all guest threads
* @param address The address of the actual thread entry point
*/
void GuestEntry(u64 address); void GuestEntry(u64 address);
/**
* @brief This saves the context from CPU registers into TLS
*/
extern "C" void SaveCtx(void); extern "C" void SaveCtx(void);
/**
* @brief This loads the context from TLS into CPU registers
*/
extern "C" void LoadCtx(void); extern "C" void LoadCtx(void);
/**
* @brief This rescales the clock to Tegra X1 levels and puts the output on stack
*/
extern "C" __noreturn void RescaleClock(void); extern "C" __noreturn void RescaleClock(void);
/**
* @brief This is used to handle all SVC calls
* @param pc The address of PC when the call was being done
* @param svc The SVC ID of the SVC being called
*/
void SvcHandler(u64 pc, u32 svc); void SvcHandler(u64 pc, u32 svc);
} }
} }

View File

@ -16,27 +16,27 @@ namespace skyline {
* @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes * @brief Creates a BRK instruction with a specific immediate value, used for generating BRK opcodes
* @param value The immediate value of the instruction * @param value The immediate value of the instruction
*/ */
explicit Brk(u16 value) { inline constexpr Brk(u16 value) {
sig0 = 0x0; // First 5 bits of a BRK instruction are 0 sig0 = 0x0;
this->value = value; this->value = value;
sig1 = 0x6A1; // Last 11 bits of a BRK instruction stored as u16 sig1 = 0x6A1;
} }
/** /**
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid BRK instruction * @return If the opcode represents a valid BRK instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig0 == 0x0 && sig1 == 0x6A1); return (sig0 == 0x0 && sig1 == 0x6A1);
} }
union { union {
struct { struct {
u8 sig0 : 5; u8 sig0 : 5; //!< 5-bit signature (0x0)
u32 value : 16; u32 value : 16; //!< 16-bit immediate value
u16 sig1 : 11; u16 sig1 : 11; //!< 11-bit signature (0x6A1)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Brk) == sizeof(u32)); static_assert(sizeof(Brk) == sizeof(u32));
@ -49,17 +49,17 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid SVC instruction * @return If the opcode represents a valid SVC instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig0 == 0x1 && sig1 == 0x6A0); return (sig0 == 0x1 && sig1 == 0x6A0);
} }
union { union {
struct { struct {
u8 sig0 : 5; u8 sig0 : 5; //!< 5-bit signature (0x0)
u32 value : 16; u32 value : 16; //!< 16-bit immediate value
u16 sig1 : 11; u16 sig1 : 11; //!< 11-bit signature (0x6A1)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Svc) == sizeof(u32)); static_assert(sizeof(Svc) == sizeof(u32));
@ -73,27 +73,27 @@ namespace skyline {
* @param srcReg The source system register * @param srcReg The source system register
* @param dstReg The destination Xn register * @param dstReg The destination Xn register
*/ */
Mrs(u32 srcReg, regs::X dstReg) { inline constexpr Mrs(u32 srcReg, regs::X dstReg) {
this->srcReg = srcReg; this->srcReg = srcReg;
this->destReg = dstReg; this->destReg = dstReg;
sig = 0xD53; // Last 12 bits of a MRS instruction stored as u16 sig = 0xD53;
} }
/** /**
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid MRS instruction * @return If the opcode represents a valid MRS instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0xD53); return (sig == 0xD53);
} }
union { union {
struct { struct {
u8 destReg : 5; u8 destReg : 5; //!< 5-bit destination register
u32 srcReg : 15; u32 srcReg : 15; //!< 15-bit source register
u16 sig : 12; u16 sig : 12; //!< 16-bit signature (0xD53)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Mrs) == sizeof(u32)); static_assert(sizeof(Mrs) == sizeof(u32));
@ -107,7 +107,7 @@ namespace skyline {
* @brief Creates a B instruction with a specific offset * @brief Creates a B instruction with a specific offset
* @param offset The offset to encode in the instruction (Should be 32-bit aligned) * @param offset The offset to encode in the instruction (Should be 32-bit aligned)
*/ */
explicit B(i64 offset) { inline constexpr B(i64 offset) {
this->offset = static_cast<i32>(offset / 4); this->offset = static_cast<i32>(offset / 4);
sig = 0x5; sig = 0x5;
} }
@ -116,7 +116,7 @@ namespace skyline {
* @brief Returns the offset of the instruction * @brief Returns the offset of the instruction
* @return The offset encoded within the instruction * @return The offset encoded within the instruction
*/ */
inline i32 Offset() { inline constexpr i32 Offset() {
return offset * 4; return offset * 4;
} }
@ -124,16 +124,16 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid Branch instruction * @return If the opcode represents a valid Branch instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0x5); return (sig == 0x5);
} }
union { union {
struct { struct {
i32 offset : 26; i32 offset : 26; //!< 26-bit branch offset
u8 sig : 6; u8 sig : 6; //!< 6-bit signature (0x5)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(B) == sizeof(u32)); static_assert(sizeof(B) == sizeof(u32));
@ -147,7 +147,7 @@ namespace skyline {
* @brief Creates a BL instruction with a specific offset * @brief Creates a BL instruction with a specific offset
* @param offset The offset to encode in the instruction (Should be 32-bit aligned) * @param offset The offset to encode in the instruction (Should be 32-bit aligned)
*/ */
explicit BL(i64 offset) { inline constexpr BL(i64 offset) {
this->offset = static_cast<i32>(offset / 4); this->offset = static_cast<i32>(offset / 4);
sig = 0x25; sig = 0x25;
} }
@ -156,7 +156,7 @@ namespace skyline {
* @brief Returns the offset of the instruction * @brief Returns the offset of the instruction
* @return The offset encoded within the instruction * @return The offset encoded within the instruction
*/ */
inline i32 Offset() { inline constexpr i32 Offset() {
return offset * 4; return offset * 4;
} }
@ -164,16 +164,16 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid Branch Linked instruction * @return If the opcode represents a valid Branch Linked instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0x85); return (sig == 0x25);
} }
union { union {
struct { struct {
i32 offset : 26; i32 offset : 26; //!< 26-bit branch offset
u8 sig : 6; u8 sig : 6; //!< 6-bit signature (0x25)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(BL) == sizeof(u32)); static_assert(sizeof(BL) == sizeof(u32));
@ -189,7 +189,7 @@ namespace skyline {
* @param imm16 The 16-bit value to store * @param imm16 The 16-bit value to store
* @param shift The offset (in bits and 16-bit aligned) in the register to store the value at * @param shift The offset (in bits and 16-bit aligned) in the register to store the value at
*/ */
Movz(regs::X destReg, u16 imm16, u8 shift = 0) { inline constexpr Movz(regs::X destReg, u16 imm16, u8 shift = 0) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
this->imm16 = imm16; this->imm16 = imm16;
hw = static_cast<u8>(shift / 16); hw = static_cast<u8>(shift / 16);
@ -203,7 +203,7 @@ namespace skyline {
* @param imm16 The 16-bit value to store * @param imm16 The 16-bit value to store
* @param shift The offset (in bits and 16-bit aligned) in the register to store the value at * @param shift The offset (in bits and 16-bit aligned) in the register to store the value at
*/ */
Movz(regs::W destReg, u16 imm16, u8 shift = 0) { inline constexpr Movz(regs::W destReg, u16 imm16, u8 shift = 0) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
this->imm16 = imm16; this->imm16 = imm16;
hw = static_cast<u8>(shift / 16); hw = static_cast<u8>(shift / 16);
@ -215,7 +215,7 @@ namespace skyline {
* @brief Returns the offset of the instruction * @brief Returns the offset of the instruction
* @return The offset encoded within the instruction * @return The offset encoded within the instruction
*/ */
inline u8 Shift() { inline constexpr u8 Shift() {
return static_cast<u8>(hw * 16); return static_cast<u8>(hw * 16);
} }
@ -223,19 +223,19 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid MOVZ instruction * @return If the opcode represents a valid MOVZ instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0xA5); return (sig == 0xA5);
} }
union { union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
u8 destReg : 5; u8 destReg : 5; //!< 5-bit destination register
u16 imm16 : 16; u16 imm16 : 16; //!< 16-bit immediate value
u8 hw : 2; u8 hw : 2; //!< 2-bit offset
u8 sig : 8; u8 sig : 8; //!< 8-bit signature (0xA5)
u8 sf : 1; u8 sf : 1; //!< 1-bit register type
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Movz) == sizeof(u32)); static_assert(sizeof(Movz) == sizeof(u32));
@ -251,7 +251,7 @@ namespace skyline {
* @param imm16 The 16-bit value to store * @param imm16 The 16-bit value to store
* @param shift The offset (in bits and 16-bit aligned) in the register to store the value at * @param shift The offset (in bits and 16-bit aligned) in the register to store the value at
*/ */
Movk(regs::X destReg, u16 imm16, u8 shift = 0) { inline constexpr Movk(regs::X destReg, u16 imm16, u8 shift = 0) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
this->imm16 = imm16; this->imm16 = imm16;
hw = static_cast<u8>(shift / 16); hw = static_cast<u8>(shift / 16);
@ -265,7 +265,7 @@ namespace skyline {
* @param imm16 The 16-bit value to store * @param imm16 The 16-bit value to store
* @param shift The offset (in bits and 16-bit aligned) in the register to store the value at * @param shift The offset (in bits and 16-bit aligned) in the register to store the value at
*/ */
Movk(regs::W destReg, u16 imm16, u8 shift = 0) { inline constexpr Movk(regs::W destReg, u16 imm16, u8 shift = 0) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
this->imm16 = imm16; this->imm16 = imm16;
hw = static_cast<u8>(shift / 16); hw = static_cast<u8>(shift / 16);
@ -277,7 +277,7 @@ namespace skyline {
* @brief Returns the offset of the instruction * @brief Returns the offset of the instruction
* @return The offset encoded within the instruction * @return The offset encoded within the instruction
*/ */
inline u8 Shift() { inline constexpr u8 Shift() {
return static_cast<u8>(hw * 16); return static_cast<u8>(hw * 16);
} }
@ -285,24 +285,29 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid MOVK instruction * @return If the opcode represents a valid MOVK instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0xE5); return (sig == 0xE5);
} }
union { union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
u8 destReg : 5; u8 destReg : 5; //!< 5-bit destination register
u16 imm16 : 16; u16 imm16 : 16; //!< 16-bit immediate value
u8 hw : 2; u8 hw : 2; //!< 2-bit offset
u8 sig : 8; u8 sig : 8; //!< 8-bit signature (0xA5)
u8 sf : 1; u8 sf : 1; //!< 1-bit register type
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Movk) == sizeof(u32)); static_assert(sizeof(Movk) == sizeof(u32));
const std::vector<u32> MoveU64Reg(regs::X destReg, u64 value) { /**
* @param destReg The destination register of the operation
* @param value The 64-bit value to insert into the register
* @return A vector with the instructions to insert the value
*/
inline const std::vector<u32> MoveU64Reg(regs::X destReg, u64 value) {
union { union {
u64 val; u64 val;
struct { struct {
@ -328,7 +333,12 @@ namespace skyline {
return instr; return instr;
} }
const std::vector<u32> MoveU32Reg(regs::X destReg, u32 value) { /**
* @param destReg The destination register of the operation
* @param value The 32-bit value to insert into the register
* @return A vector with the instructions to insert the value
*/
inline const std::vector<u32> MoveU32Reg(regs::X destReg, u32 value) {
union { union {
u32 val; u32 val;
struct { struct {
@ -356,12 +366,12 @@ namespace skyline {
* @param destReg The destination Xn register to store the value in * @param destReg The destination Xn register to store the value in
* @param srcReg The source Xn register to retrieve the value from * @param srcReg The source Xn register to retrieve the value from
*/ */
Mov(regs::X destReg, regs::X srcReg) { inline constexpr Mov(regs::X destReg, regs::X srcReg) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
zeroReg = 0x1F; sig0 = 0x1F;
imm6 = 0; imm6 = 0;
this->srcReg = static_cast<u8>(srcReg); this->srcReg = static_cast<u8>(srcReg);
sig = 0x150; sig1 = 0x150;
sf = 1; sf = 1;
} }
@ -370,12 +380,12 @@ namespace skyline {
* @param destReg The destination Wn register to store the value in * @param destReg The destination Wn register to store the value in
* @param srcReg The source Wn register to retrieve the value from * @param srcReg The source Wn register to retrieve the value from
*/ */
Mov(regs::W destReg, regs::W srcReg) { inline constexpr Mov(regs::W destReg, regs::W srcReg) {
this->destReg = static_cast<u8>(destReg); this->destReg = static_cast<u8>(destReg);
zeroReg = 0x1F; sig0 = 0x1F;
imm6 = 0; imm6 = 0;
this->srcReg = static_cast<u8>(srcReg); this->srcReg = static_cast<u8>(srcReg);
sig = 0x150; sig1 = 0x150;
sf = 0; sf = 0;
} }
@ -383,20 +393,20 @@ namespace skyline {
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid MOVZ instruction * @return If the opcode represents a valid MOVZ instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig == 0x150); return (sig0 == 0x1F) && (sig1 == 0x150);
} }
union { union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
u8 destReg : 5; u8 destReg : 5; //!< 5-bit destination register
u8 zeroReg : 5; u8 sig0 : 5; //!< 5-bit signature (0x1F)
u8 imm6 : 6; u8 imm6 : 6; //!< 6-bit immediate value
u8 srcReg : 5; u8 srcReg : 5; //!< 5-bit source register
u16 sig : 10; u16 sig1 : 10; //!< 10-bit signature (0x150)
u8 sf : 1; u8 sf : 1; //!< 1-bit register type
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Mov) == sizeof(u32)); static_assert(sizeof(Mov) == sizeof(u32));
@ -410,27 +420,27 @@ namespace skyline {
* @brief Creates a LDR (immediate) instruction * @brief Creates a LDR (immediate) instruction
* @param raw The raw value of the whole instruction * @param raw The raw value of the whole instruction
*/ */
Ldr(u32 raw) : raw(raw) {} inline constexpr Ldr(u32 raw) : raw(raw) {}
/** /**
* @brief Returns if the opcode is valid or not * @brief Returns if the opcode is valid or not
* @return If the opcode represents a valid FCVTZU instruction * @return If the opcode represents a valid FCVTZU instruction
*/ */
inline bool Verify() { inline constexpr bool Verify() {
return (sig0 == 0x0 && sig1 == 0x1CA && sig2 == 0x1); return (sig0 == 0x0 && sig1 == 0x1CA && sig2 == 0x1);
} }
union { union {
struct __attribute__((packed)) { struct __attribute__((packed)) {
u8 destReg : 5; u8 destReg : 5; //!< 5-bit destination register
u8 srcReg : 5; u8 srcReg : 5; //!< 5-bit source register
u8 sig0 : 2; u8 sig0 : 2; //!< 2-bit signature (0x0)
u16 imm : 9; u16 imm : 9; //!< 6-bit immediate value
u16 sig1 : 9; u16 sig1 : 9; //!< 9-bit signature (0x1CA)
u8 x : 1; u8 sf : 1; //!< 1-bit register type
u8 sig2 : 1; u8 sig2 : 1; //!< 1-bit signature (0x1)
}; };
u32 raw{}; u32 raw{}; //!< The raw value of the instruction
}; };
}; };
static_assert(sizeof(Ldr) == sizeof(u32)); static_assert(sizeof(Ldr) == sizeof(u32));