Archived
Compare commits
190
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ea3a6261d | ||
|
|
a6a6f51f0b | ||
|
|
21e1f791ad | ||
|
|
be6f5791fa | ||
|
|
ac818f304d | ||
|
|
ad60449073 | ||
|
|
b45b3589fa | ||
|
|
1fb7e8fcea | ||
|
|
5f9d0beafb | ||
|
|
4c0d1c75aa | ||
|
|
2f3abf2f76 | ||
|
|
62768bf81e | ||
|
|
f6be8ec006 | ||
|
|
a8f56b6e27 | ||
|
|
76ea0db25d | ||
|
|
ec1b820c18 | ||
|
|
64329cf0f6 | ||
|
|
9de0aed84d | ||
|
|
bb4e2766d1 | ||
|
|
0996d15bd4 | ||
|
|
6305efa7c2 | ||
|
|
de79adc50d | ||
|
|
0473aa5344 | ||
|
|
a45fcd28db | ||
|
|
0f15032210 | ||
|
|
efc11d87a5 | ||
|
|
4a19e27926 | ||
|
|
c15cdb0955 | ||
|
|
6609d12582 | ||
|
|
b5341700aa | ||
|
|
0b5062d21c | ||
|
|
fbca690b3b | ||
|
|
235a7e6e24 | ||
|
|
62d21e1156 | ||
|
|
9c51d6eade | ||
|
|
2878dca6b5 | ||
|
|
c28e8fd00c | ||
|
|
b3cc9d2346 | ||
|
|
933f08494c | ||
|
|
21f8eab432 | ||
|
|
6ddb8da07f | ||
|
|
edf456c59f | ||
|
|
42efced1eb | ||
|
|
c376e34b2b | ||
|
|
f579ec6e48 | ||
|
|
fd20e66f1f | ||
|
|
5d69b79232 | ||
|
|
2edd68d1bd | ||
|
|
7ffa7667b6 | ||
|
|
93d89e07ca | ||
|
|
17dcba4b90 | ||
|
|
39d2518fdd | ||
|
|
a365110054 | ||
|
|
d2efb23ff7 | ||
|
|
04b7a09b19 | ||
|
|
72b11beac5 | ||
|
|
e87b7d5fd0 | ||
|
|
5a2b96ef3e | ||
|
|
c6b99cd155 | ||
|
|
b1306c3a47 | ||
|
|
0d6bf924ed | ||
|
|
86de536c8f | ||
|
|
051dd5e2d3 | ||
|
|
e3942be776 | ||
|
|
6ee484a771 | ||
|
|
60808c8649 | ||
|
|
0432803d82 | ||
|
|
4f5d9214ed | ||
|
|
d42d2ce533 | ||
|
|
236d12d7f5 | ||
|
|
e1b6cab890 | ||
|
|
8361f88718 | ||
|
|
2ec7ea4b41 | ||
|
|
b24965d321 | ||
|
|
244bf6d2f2 | ||
|
|
1a4465a371 | ||
|
|
fa82a50824 | ||
|
|
6dc17857da | ||
|
|
11a30caae8 | ||
|
|
ac1a26a10c | ||
|
|
7a199e122d | ||
|
|
d8c3d2e19c | ||
|
|
375755999a | ||
|
|
9996fd4833 | ||
|
|
149b3136d2 | ||
|
|
ac8f8b0539 | ||
|
|
b2cbf90d0b | ||
|
|
373145478e | ||
|
|
55b0cea94f | ||
|
|
5b17599aa2 | ||
|
|
4cfb15c7cd | ||
|
|
63da7f8d57 | ||
|
|
fb4012fbd1 | ||
|
|
24449f1c0f | ||
|
|
fd303c8343 | ||
|
|
346b177a87 | ||
|
|
d4ec131fa7 | ||
|
|
48370a4555 | ||
|
|
36b076774e | ||
|
|
482a4ec253 | ||
|
|
2fb28364c5 | ||
|
|
8460f4ab7f | ||
|
|
3fd51cc68c | ||
|
|
551822916c | ||
|
|
37db31fb4b | ||
|
|
e2da306eee | ||
|
|
41051f8f34 | ||
|
|
2a7449fa1e | ||
|
|
a6c48ceaac | ||
|
|
1e30b68507 | ||
|
|
ed793471bb | ||
|
|
58fb815f32 | ||
|
|
3cc8bd0854 | ||
|
|
a27850f841 | ||
|
|
fb330cddea | ||
|
|
b76c5bf0d6 | ||
|
|
001c6349f7 | ||
|
|
ee6a11dae6 | ||
|
|
2e27b025cc | ||
|
|
f0a004be9d | ||
|
|
3422c7cd5c | ||
|
|
ad79a28705 | ||
|
|
9fdbc3ff38 | ||
|
|
602bc6e06a | ||
|
|
6cb76fc256 | ||
|
|
fbcd389580 | ||
|
|
b25b7848c6 | ||
|
|
6c986d38d8 | ||
|
|
a1ebd83d2a | ||
|
|
8aed551813 | ||
|
|
1e6a0086e9 | ||
|
|
119d4a8b43 | ||
|
|
9841b16122 | ||
|
|
fbda1424f3 | ||
|
|
fe2d5cb2f9 | ||
|
|
3ff59ba45d | ||
|
|
db5765b342 | ||
|
|
075e04249a | ||
|
|
207f778ee6 | ||
|
|
f4f90c5e65 | ||
|
|
bc4ea30815 | ||
|
|
e921201f7b | ||
|
|
e6aa6e5842 | ||
|
|
4418fa7e4f | ||
|
|
adaa7e1c04 | ||
|
|
0eb1db0e7e | ||
|
|
e48597b2b7 | ||
|
|
458c773e19 | ||
|
|
b3f40f9b15 | ||
|
|
6419ad471e | ||
|
|
759061b569 | ||
|
|
2115e9ceae | ||
|
|
2bea95c1a7 | ||
|
|
7001b693ae | ||
|
|
e6f11081eb | ||
|
|
09db0cd35d | ||
|
|
980c8031c3 | ||
|
|
b86d7a517d | ||
|
|
b7478965ab | ||
|
|
bf4a6deb86 | ||
|
|
ffe730219d | ||
|
|
60c926c921 | ||
|
|
9371a09b71 | ||
|
|
4c3a7386b0 | ||
|
|
82c26acfc8 | ||
|
|
3a86f4f9de | ||
|
|
74ff1d455a | ||
|
|
aa12e93177 | ||
|
|
ae4322c1b9 | ||
|
|
9180ad1f9c | ||
|
|
ee6a068b06 | ||
|
|
b9b165465d | ||
|
|
b97853ff5a | ||
|
|
b7f023756e | ||
|
|
2095ac985b | ||
|
|
3fb8fe765a | ||
|
|
5fd226b670 | ||
|
|
417076f8e6 | ||
|
|
70839bbbf2 | ||
|
|
8db0cc5d05 | ||
|
|
212fb1c8ff | ||
|
|
f74f98f361 | ||
|
|
f074092a78 | ||
|
|
633c0d21a0 | ||
|
|
51f6fbe0dd | ||
|
|
de45d06878 | ||
|
|
c7038cafa5 | ||
|
|
40f50b0ec0 | ||
|
|
b360fc2c75 | ||
|
|
e21f8dc379 |
No files matched your search
+6
-7
@@ -1,4 +1,3 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
# BasedOnStyle: LLVM
|
# BasedOnStyle: LLVM
|
||||||
# should be in line with IndentWidth
|
# should be in line with IndentWidth
|
||||||
@@ -13,8 +12,8 @@ AllowAllParametersOfDeclarationOnNextLine: true
|
|||||||
AllowShortBlocksOnASingleLine: false
|
AllowShortBlocksOnASingleLine: false
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: All
|
AllowShortFunctionsOnASingleLine: All
|
||||||
AllowShortIfStatementsOnASingleLine: true
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
AllowShortLoopsOnASingleLine: true
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
@@ -39,8 +38,8 @@ BreakBeforeTernaryOperators: true
|
|||||||
BreakConstructorInitializersBeforeComma: true
|
BreakConstructorInitializersBeforeComma: true
|
||||||
BreakAfterJavaFieldAnnotations: false
|
BreakAfterJavaFieldAnnotations: false
|
||||||
BreakStringLiterals: true
|
BreakStringLiterals: true
|
||||||
ColumnLimit: 120
|
ColumnLimit: 140
|
||||||
CommentPragmas: '^ IWYU pragma:'
|
CommentPragmas: '^( IWYU pragma:| @suppress)'
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
ConstructorInitializerIndentWidth: 0
|
ConstructorInitializerIndentWidth: 0
|
||||||
ContinuationIndentWidth: 4
|
ContinuationIndentWidth: 4
|
||||||
@@ -76,13 +75,13 @@ PenaltyBreakFirstLessLess: 120
|
|||||||
PenaltyBreakString: 1000
|
PenaltyBreakString: 1000
|
||||||
PenaltyExcessCharacter: 1000000
|
PenaltyExcessCharacter: 1000000
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Right
|
PointerAlignment: Left
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: true
|
SortIncludes: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
SpaceBeforeAssignmentOperators: true
|
SpaceBeforeAssignmentOperators: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: Never
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: false
|
SpacesInAngles: false
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
/*.il
|
/*.il
|
||||||
|
/.settings
|
||||||
/avr-instr.html
|
/avr-instr.html
|
||||||
/blink.S
|
/blink.S
|
||||||
/flash.*
|
/flash.*
|
||||||
@@ -14,7 +15,6 @@
|
|||||||
/*.ods
|
/*.ods
|
||||||
/build*/
|
/build*/
|
||||||
/*.logs
|
/*.logs
|
||||||
language.settings.xml
|
|
||||||
/*.gtkw
|
/*.gtkw
|
||||||
/Debug wo LLVM/
|
/Debug wo LLVM/
|
||||||
/*.txdb
|
/*.txdb
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
eclipse.preferences.version=1
|
|
||||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
|
||||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return\\")",implicit\=>false}
|
|
||||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
|
||||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused return value\\")"}
|
|
||||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
|
||||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting comments\\")"}
|
|
||||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
|
||||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line comments\\")"}
|
|
||||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
|
||||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No return value\\")",implicit\=>false}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract class cannot be instantiated\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous problem\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment in condition\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment to itself\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No break at end of case\\")",no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false,enable_fallthrough_quickfix_param\=>false}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching by reference is recommended\\")",unknown\=>false,exceptions\=>()}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular inheritance\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class members should be properly initialized\\")",skip\=>true}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.DecltypeAutoProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid 'decltype(auto)' specifier\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field cannot be resolved\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function cannot be resolved\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid arguments\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid template argument\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label statement not found\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member declaration not found\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method cannot be resolved\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name convention for function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class has a virtual method and non-virtual destructor\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid overload\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redeclaration\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid redefinition\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return with parenthesis\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format String Vulnerability\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement has no effect\\")",macro\=>true,exceptions\=>()}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested parenthesis around expression\\")",paramNot\=>false}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious semicolon\\")",else\=>false,afterelse\=>false}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type cannot be resolved\\")"}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused function declaration\\")",macro\=>true}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused static function\\")",macro\=>true}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused variable declaration in file scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
|
||||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol is not resolved\\")"}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
eclipse.preferences.version=1
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/append=true
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.debug.1751741082/appendContributed=true
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/LLVM_HOME/delimiter=\:
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/LLVM_HOME/operation=append
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/LLVM_HOME/value=/usr/lib/llvm-6.0
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/append=true
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/appendContributed=true
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/delimiter=\:
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/operation=append
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/LLVM_HOME/value=/usr/lib/llvm-6.0
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/append=true
|
|
||||||
environment/project/cdt.managedbuild.config.gnu.exe.release.1745230171/appendContributed=true
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
eclipse.preferences.version=1
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/CPATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/CPATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/CPLUS_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/CPLUS_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/C_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/C_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/append=true
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.debug.1751741082/appendContributed=true
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/CPATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/CPATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/CPLUS_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/CPLUS_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/C_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/C_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/append=true
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/appendContributed=true
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/CPATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/CPATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/CPLUS_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/CPLUS_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/C_INCLUDE_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/C_INCLUDE_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/append=true
|
|
||||||
environment/buildEnvironmentInclude/cdt.managedbuild.config.gnu.exe.release.1745230171/appendContributed=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1751741082/LIBRARY_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1751741082/LIBRARY_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1751741082/append=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.debug.1751741082/appendContributed=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/LIBRARY_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/LIBRARY_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/append=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171.1259602404/appendContributed=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171/LIBRARY_PATH/delimiter=\:
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171/LIBRARY_PATH/operation=remove
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171/append=true
|
|
||||||
environment/buildEnvironmentLibrary/cdt.managedbuild.config.gnu.exe.release.1745230171/appendContributed=true
|
|
||||||
+61
-25
@@ -1,5 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.12)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
#
|
#
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
@@ -19,12 +20,16 @@ set(LIB_SOURCES
|
|||||||
src/iss/arch/tgc5c.cpp
|
src/iss/arch/tgc5c.cpp
|
||||||
src/vm/interp/vm_tgc5c.cpp
|
src/vm/interp/vm_tgc5c.cpp
|
||||||
src/vm/fp_functions.cpp
|
src/vm/fp_functions.cpp
|
||||||
|
src/iss/debugger/csr_names.cpp
|
||||||
|
src/iss/semihosting/semihosting.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WITH_TCC)
|
if(WITH_TCC)
|
||||||
list(APPEND LIB_SOURCES
|
list(APPEND LIB_SOURCES
|
||||||
src/vm/tcc/vm_tgc5c.cpp
|
src/vm/tcc/vm_tgc5c.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_LLVM)
|
if(WITH_LLVM)
|
||||||
list(APPEND LIB_SOURCES
|
list(APPEND LIB_SOURCES
|
||||||
src/vm/llvm/vm_tgc5c.cpp
|
src/vm/llvm/vm_tgc5c.cpp
|
||||||
@@ -32,15 +37,24 @@ if(WITH_LLVM)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_ASMJIT)
|
||||||
|
list(APPEND LIB_SOURCES
|
||||||
|
src/vm/asmjit/vm_tgc5c.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
# library files
|
# library files
|
||||||
FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp)
|
FILE(GLOB GEN_ISS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp)
|
||||||
FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp)
|
FILE(GLOB GEN_VM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp)
|
||||||
|
FILE(GLOB GEN_YAML_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/contrib/instr/*.yaml)
|
||||||
list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES})
|
list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES})
|
||||||
|
|
||||||
foreach(FILEPATH ${GEN_ISS_SOURCES})
|
foreach(FILEPATH ${GEN_ISS_SOURCES})
|
||||||
get_filename_component(CORE ${FILEPATH} NAME_WE)
|
get_filename_component(CORE ${FILEPATH} NAME_WE)
|
||||||
string(TOUPPER ${CORE} CORE)
|
string(TOUPPER ${CORE} CORE)
|
||||||
list(APPEND LIB_DEFINES CORE_${CORE})
|
list(APPEND LIB_DEFINES CORE_${CORE})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
message(STATUS "Core defines are ${LIB_DEFINES}")
|
message(STATUS "Core defines are ${LIB_DEFINES}")
|
||||||
|
|
||||||
if(WITH_LLVM)
|
if(WITH_LLVM)
|
||||||
@@ -53,17 +67,18 @@ if(WITH_TCC)
|
|||||||
list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES})
|
list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(TARGET RapidJSON OR TARGET RapidJSON::RapidJSON)
|
if(WITH_ASMJIT)
|
||||||
|
FILE(GLOB TCC_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/asmjit/vm_*.cpp)
|
||||||
|
list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TARGET yaml-cpp::yaml-cpp)
|
||||||
list(APPEND LIB_SOURCES
|
list(APPEND LIB_SOURCES
|
||||||
src/iss/plugin/cycle_estimate.cpp
|
src/iss/plugin/cycle_estimate.cpp
|
||||||
src/iss/plugin/pctrace.cpp
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
if(TARGET jsoncpp::jsoncpp)
|
|
||||||
list(APPEND LIB_SOURCES
|
|
||||||
src/iss/plugin/instruction_count.cpp
|
src/iss/plugin/instruction_count.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Define the library
|
# Define the library
|
||||||
add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES})
|
add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES})
|
||||||
|
|
||||||
@@ -72,35 +87,36 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|||||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
|
target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC src)
|
target_include_directories(${PROJECT_NAME} PUBLIC src)
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC src-gen)
|
target_include_directories(${PROJECT_NAME} PUBLIC src-gen)
|
||||||
|
|
||||||
target_force_link_libraries(${PROJECT_NAME} PRIVATE dbt-rise-core)
|
target_force_link_libraries(${PROJECT_NAME} PRIVATE dbt-rise-core)
|
||||||
|
|
||||||
# only re-export the include paths
|
# only re-export the include paths
|
||||||
get_target_property(DBT_CORE_INCL dbt-rise-core INTERFACE_INCLUDE_DIRECTORIES)
|
get_target_property(DBT_CORE_INCL dbt-rise-core INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE ${DBT_CORE_INCL})
|
target_include_directories(${PROJECT_NAME} INTERFACE ${DBT_CORE_INCL})
|
||||||
get_target_property(DBT_CORE_DEFS dbt-rise-core INTERFACE_COMPILE_DEFINITIONS)
|
get_target_property(DBT_CORE_DEFS dbt-rise-core INTERFACE_COMPILE_DEFINITIONS)
|
||||||
|
|
||||||
|
if(NOT(DBT_CORE_DEFS STREQUAL DBT_CORE_DEFS-NOTFOUND))
|
||||||
target_compile_definitions(${PROJECT_NAME} INTERFACE ${DBT_CORE_DEFS})
|
target_compile_definitions(${PROJECT_NAME} INTERFACE ${DBT_CORE_DEFS})
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC elfio::elfio softfloat scc-util Boost::coroutine)
|
target_link_libraries(${PROJECT_NAME} PUBLIC elfio::elfio softfloat scc-util Boost::coroutine)
|
||||||
if(TARGET jsoncpp::jsoncpp)
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC jsoncpp::jsoncpp)
|
if(TARGET yaml-cpp::yaml-cpp)
|
||||||
endif()
|
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_PLUGINS)
|
||||||
if(TARGET lz4::lz4)
|
target_link_libraries(${PROJECT_NAME} PUBLIC yaml-cpp::yaml-cpp)
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_LZ4)
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC lz4::lz4)
|
|
||||||
endif()
|
|
||||||
if(TARGET RapidJSON)
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC RapidJSON)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_LLVM)
|
# if(WITH_LLVM)
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC ${LLVM_DEFINITIONS})
|
# target_compile_definitions(${PROJECT_NAME} PUBLIC ${LLVM_DEFINITIONS})
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS})
|
# target_include_directories(${PROJECT_NAME} PUBLIC ${LLVM_INCLUDE_DIRS})
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
target_link_libraries( ${PROJECT_NAME} PUBLIC ${LLVM_LIBRARIES})
|
# if(BUILD_SHARED_LIBS)
|
||||||
endif()
|
# target_link_libraries(${PROJECT_NAME} PUBLIC ${LLVM_LIBRARIES})
|
||||||
endif()
|
# endif()
|
||||||
|
# endif()
|
||||||
|
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
@@ -120,13 +136,17 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss COMPONENT ${PROJECT_NAME}
|
|||||||
FILES_MATCHING # install only matched files
|
FILES_MATCHING # install only matched files
|
||||||
PATTERN "*.h" # select header files
|
PATTERN "*.h" # select header files
|
||||||
)
|
)
|
||||||
|
install(FILES ${GEN_YAML_SOURCES} DESTINATION share/tgc-vp)
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
#
|
#
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
|
set(CMAKE_INSTALL_RPATH $ORIGIN/../${CMAKE_INSTALL_LIBDIR})
|
||||||
project(tgc-sim)
|
project(tgc-sim)
|
||||||
find_package(Boost COMPONENTS program_options thread REQUIRED)
|
find_package(Boost COMPONENTS program_options thread REQUIRED)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} src/main.cpp)
|
add_executable(${PROJECT_NAME} src/main.cpp)
|
||||||
|
|
||||||
if(TARGET ${CORE_NAME}_cpp)
|
if(TARGET ${CORE_NAME}_cpp)
|
||||||
list(APPEND TGC_SOURCES ${${CORE_NAME}_OUTPUT_FILES})
|
list(APPEND TGC_SOURCES ${${CORE_NAME}_OUTPUT_FILES})
|
||||||
else()
|
else()
|
||||||
@@ -152,7 +172,6 @@ endforeach()
|
|||||||
# if(WITH_TCC)
|
# if(WITH_TCC)
|
||||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_TCC)
|
# target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_TCC)
|
||||||
# endif()
|
# endif()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc fmt::fmt)
|
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc fmt::fmt)
|
||||||
|
|
||||||
if(TARGET Boost::program_options)
|
if(TARGET Boost::program_options)
|
||||||
@@ -160,7 +179,9 @@ if(TARGET Boost::program_options)
|
|||||||
else()
|
else()
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS})
|
||||||
|
|
||||||
if(Tcmalloc_FOUND)
|
if(Tcmalloc_FOUND)
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${Tcmalloc_LIBRARIES})
|
target_link_libraries(${PROJECT_NAME} PUBLIC ${Tcmalloc_LIBRARIES})
|
||||||
endif(Tcmalloc_FOUND)
|
endif(Tcmalloc_FOUND)
|
||||||
@@ -179,15 +200,23 @@ if(BUILD_TESTING)
|
|||||||
# ... CMake code to create tests ...
|
# ... CMake code to create tests ...
|
||||||
add_test(NAME tgc-sim-interp
|
add_test(NAME tgc-sim-interp
|
||||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend interp)
|
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend interp)
|
||||||
|
|
||||||
if(WITH_TCC)
|
if(WITH_TCC)
|
||||||
add_test(NAME tgc-sim-tcc
|
add_test(NAME tgc-sim-tcc
|
||||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend tcc)
|
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend tcc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_LLVM)
|
if(WITH_LLVM)
|
||||||
add_test(NAME tgc-sim-llvm
|
add_test(NAME tgc-sim-llvm
|
||||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend llvm)
|
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend llvm)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(WITH_ASMJIT)
|
||||||
|
add_test(NAME tgc-sim-asmjit
|
||||||
|
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend asmjit)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
#
|
#
|
||||||
# ##############################################################################
|
# ##############################################################################
|
||||||
@@ -202,6 +231,7 @@ if(TARGET scc-sysc)
|
|||||||
add_library(${PROJECT_NAME} ${LIB_SOURCES})
|
add_library(${PROJECT_NAME} ${LIB_SOURCES})
|
||||||
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC)
|
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC)
|
||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||||
|
|
||||||
foreach(F IN LISTS TGC_SOURCES)
|
foreach(F IN LISTS TGC_SOURCES)
|
||||||
if(${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
if(${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
||||||
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
||||||
@@ -209,11 +239,12 @@ if(TARGET scc-sysc)
|
|||||||
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc)
|
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc)
|
||||||
|
|
||||||
# if(WITH_LLVM)
|
# if(WITH_LLVM)
|
||||||
# target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
# target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||||
# endif()
|
# endif()
|
||||||
|
|
||||||
set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h)
|
set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h)
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION ${PROJECT_VERSION}
|
||||||
@@ -231,3 +262,8 @@ if(TARGET scc-sysc)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
project(elfio-test)
|
||||||
|
find_package(Boost COMPONENTS program_options thread REQUIRED)
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} src/elfio.cpp)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PUBLIC elfio::elfio)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
/*.yaml
|
||||||
@@ -1,536 +1,623 @@
|
|||||||
|
|
||||||
RV32I:
|
RVI:
|
||||||
- LUI:
|
LUI:
|
||||||
|
index: 0
|
||||||
encoding: 0b00000000000000000000000000110111
|
encoding: 0b00000000000000000000000000110111
|
||||||
mask: 0b00000000000000000000000001111111
|
mask: 0b00000000000000000000000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- AUIPC:
|
AUIPC:
|
||||||
|
index: 1
|
||||||
encoding: 0b00000000000000000000000000010111
|
encoding: 0b00000000000000000000000000010111
|
||||||
mask: 0b00000000000000000000000001111111
|
mask: 0b00000000000000000000000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- JAL:
|
JAL:
|
||||||
|
index: 2
|
||||||
encoding: 0b00000000000000000000000001101111
|
encoding: 0b00000000000000000000000001101111
|
||||||
mask: 0b00000000000000000000000001111111
|
mask: 0b00000000000000000000000001111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: 1
|
||||||
- JALR:
|
JALR:
|
||||||
|
index: 3
|
||||||
encoding: 0b00000000000000000000000001100111
|
encoding: 0b00000000000000000000000001100111
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: [1,1]
|
||||||
- BEQ:
|
BEQ:
|
||||||
|
index: 4
|
||||||
encoding: 0b00000000000000000000000001100011
|
encoding: 0b00000000000000000000000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- BNE:
|
BNE:
|
||||||
|
index: 5
|
||||||
encoding: 0b00000000000000000001000001100011
|
encoding: 0b00000000000000000001000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- BLT:
|
BLT:
|
||||||
|
index: 6
|
||||||
encoding: 0b00000000000000000100000001100011
|
encoding: 0b00000000000000000100000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- BGE:
|
BGE:
|
||||||
|
index: 7
|
||||||
encoding: 0b00000000000000000101000001100011
|
encoding: 0b00000000000000000101000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- BLTU:
|
BLTU:
|
||||||
|
index: 8
|
||||||
encoding: 0b00000000000000000110000001100011
|
encoding: 0b00000000000000000110000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- BGEU:
|
BGEU:
|
||||||
|
index: 9
|
||||||
encoding: 0b00000000000000000111000001100011
|
encoding: 0b00000000000000000111000001100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 32
|
size: 32
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- LB:
|
LB:
|
||||||
|
index: 10
|
||||||
encoding: 0b00000000000000000000000000000011
|
encoding: 0b00000000000000000000000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- LH:
|
LH:
|
||||||
|
index: 11
|
||||||
encoding: 0b00000000000000000001000000000011
|
encoding: 0b00000000000000000001000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- LW:
|
LW:
|
||||||
|
index: 12
|
||||||
encoding: 0b00000000000000000010000000000011
|
encoding: 0b00000000000000000010000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- LBU:
|
LBU:
|
||||||
|
index: 13
|
||||||
encoding: 0b00000000000000000100000000000011
|
encoding: 0b00000000000000000100000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- LHU:
|
LHU:
|
||||||
|
index: 14
|
||||||
encoding: 0b00000000000000000101000000000011
|
encoding: 0b00000000000000000101000000000011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SB:
|
SB:
|
||||||
|
index: 15
|
||||||
encoding: 0b00000000000000000000000000100011
|
encoding: 0b00000000000000000000000000100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SH:
|
SH:
|
||||||
|
index: 16
|
||||||
encoding: 0b00000000000000000001000000100011
|
encoding: 0b00000000000000000001000000100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SW:
|
SW:
|
||||||
|
index: 17
|
||||||
encoding: 0b00000000000000000010000000100011
|
encoding: 0b00000000000000000010000000100011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- ADDI:
|
ADDI:
|
||||||
|
index: 18
|
||||||
encoding: 0b00000000000000000000000000010011
|
encoding: 0b00000000000000000000000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLTI:
|
SLTI:
|
||||||
|
index: 19
|
||||||
encoding: 0b00000000000000000010000000010011
|
encoding: 0b00000000000000000010000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLTIU:
|
SLTIU:
|
||||||
|
index: 20
|
||||||
encoding: 0b00000000000000000011000000010011
|
encoding: 0b00000000000000000011000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- XORI:
|
XORI:
|
||||||
|
index: 21
|
||||||
encoding: 0b00000000000000000100000000010011
|
encoding: 0b00000000000000000100000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- ORI:
|
ORI:
|
||||||
|
index: 22
|
||||||
encoding: 0b00000000000000000110000000010011
|
encoding: 0b00000000000000000110000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- ANDI:
|
ANDI:
|
||||||
|
index: 23
|
||||||
encoding: 0b00000000000000000111000000010011
|
encoding: 0b00000000000000000111000000010011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLLI:
|
SLLI:
|
||||||
|
index: 24
|
||||||
encoding: 0b00000000000000000001000000010011
|
encoding: 0b00000000000000000001000000010011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SRLI:
|
SRLI:
|
||||||
|
index: 25
|
||||||
encoding: 0b00000000000000000101000000010011
|
encoding: 0b00000000000000000101000000010011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SRAI:
|
SRAI:
|
||||||
|
index: 26
|
||||||
encoding: 0b01000000000000000101000000010011
|
encoding: 0b01000000000000000101000000010011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- ADD:
|
ADD:
|
||||||
|
index: 27
|
||||||
encoding: 0b00000000000000000000000000110011
|
encoding: 0b00000000000000000000000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SUB:
|
SUB:
|
||||||
|
index: 28
|
||||||
encoding: 0b01000000000000000000000000110011
|
encoding: 0b01000000000000000000000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLL:
|
SLL:
|
||||||
|
index: 29
|
||||||
encoding: 0b00000000000000000001000000110011
|
encoding: 0b00000000000000000001000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLT:
|
SLT:
|
||||||
|
index: 30
|
||||||
encoding: 0b00000000000000000010000000110011
|
encoding: 0b00000000000000000010000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SLTU:
|
SLTU:
|
||||||
|
index: 31
|
||||||
encoding: 0b00000000000000000011000000110011
|
encoding: 0b00000000000000000011000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- XOR:
|
XOR:
|
||||||
|
index: 32
|
||||||
encoding: 0b00000000000000000100000000110011
|
encoding: 0b00000000000000000100000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SRL:
|
SRL:
|
||||||
|
index: 33
|
||||||
encoding: 0b00000000000000000101000000110011
|
encoding: 0b00000000000000000101000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- SRA:
|
SRA:
|
||||||
|
index: 34
|
||||||
encoding: 0b01000000000000000101000000110011
|
encoding: 0b01000000000000000101000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- OR:
|
OR:
|
||||||
|
index: 35
|
||||||
encoding: 0b00000000000000000110000000110011
|
encoding: 0b00000000000000000110000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- AND:
|
AND:
|
||||||
|
index: 36
|
||||||
encoding: 0b00000000000000000111000000110011
|
encoding: 0b00000000000000000111000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- FENCE:
|
FENCE:
|
||||||
|
index: 37
|
||||||
encoding: 0b00000000000000000000000000001111
|
encoding: 0b00000000000000000000000000001111
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- ECALL:
|
ECALL:
|
||||||
|
index: 38
|
||||||
encoding: 0b00000000000000000000000001110011
|
encoding: 0b00000000000000000000000001110011
|
||||||
mask: 0b11111111111111111111111111111111
|
mask: 0b11111111111111111111111111111111
|
||||||
attributes: [[name:no_cont]]
|
attributes: [[name:no_cont]]
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- EBREAK:
|
EBREAK:
|
||||||
|
index: 39
|
||||||
encoding: 0b00000000000100000000000001110011
|
encoding: 0b00000000000100000000000001110011
|
||||||
mask: 0b11111111111111111111111111111111
|
mask: 0b11111111111111111111111111111111
|
||||||
attributes: [[name:no_cont]]
|
attributes: [[name:no_cont]]
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- MRET:
|
MRET:
|
||||||
|
index: 40
|
||||||
encoding: 0b00110000001000000000000001110011
|
encoding: 0b00110000001000000000000001110011
|
||||||
mask: 0b11111111111111111111111111111111
|
mask: 0b11111111111111111111111111111111
|
||||||
attributes: [[name:no_cont]]
|
attributes: [[name:no_cont]]
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- WFI:
|
WFI:
|
||||||
|
index: 41
|
||||||
encoding: 0b00010000010100000000000001110011
|
encoding: 0b00010000010100000000000001110011
|
||||||
mask: 0b11111111111111111111111111111111
|
mask: 0b11111111111111111111111111111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
Zicsr:
|
Zicsr:
|
||||||
- CSRRW:
|
CSRRW:
|
||||||
|
index: 42
|
||||||
encoding: 0b00000000000000000001000001110011
|
encoding: 0b00000000000000000001000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRRS:
|
CSRRS:
|
||||||
|
index: 43
|
||||||
encoding: 0b00000000000000000010000001110011
|
encoding: 0b00000000000000000010000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRRC:
|
CSRRC:
|
||||||
|
index: 44
|
||||||
encoding: 0b00000000000000000011000001110011
|
encoding: 0b00000000000000000011000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRRWI:
|
CSRRWI:
|
||||||
|
index: 45
|
||||||
encoding: 0b00000000000000000101000001110011
|
encoding: 0b00000000000000000101000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRRSI:
|
CSRRSI:
|
||||||
|
index: 46
|
||||||
encoding: 0b00000000000000000110000001110011
|
encoding: 0b00000000000000000110000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRRCI:
|
CSRRCI:
|
||||||
|
index: 47
|
||||||
encoding: 0b00000000000000000111000001110011
|
encoding: 0b00000000000000000111000001110011
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
Zifencei:
|
Zifencei:
|
||||||
- FENCE_I:
|
FENCE_I:
|
||||||
|
index: 48
|
||||||
encoding: 0b00000000000000000001000000001111
|
encoding: 0b00000000000000000001000000001111
|
||||||
mask: 0b00000000000000000111000001111111
|
mask: 0b00000000000000000111000001111111
|
||||||
attributes: [[name:flush]]
|
attributes: [[name:flush]]
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
RV32M:
|
RVM:
|
||||||
- MUL:
|
MUL:
|
||||||
|
index: 49
|
||||||
encoding: 0b00000010000000000000000000110011
|
encoding: 0b00000010000000000000000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- MULH:
|
MULH:
|
||||||
|
index: 50
|
||||||
encoding: 0b00000010000000000001000000110011
|
encoding: 0b00000010000000000001000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- MULHSU:
|
MULHSU:
|
||||||
|
index: 51
|
||||||
encoding: 0b00000010000000000010000000110011
|
encoding: 0b00000010000000000010000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- MULHU:
|
MULHU:
|
||||||
|
index: 52
|
||||||
encoding: 0b00000010000000000011000000110011
|
encoding: 0b00000010000000000011000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- DIV:
|
DIV:
|
||||||
|
index: 53
|
||||||
encoding: 0b00000010000000000100000000110011
|
encoding: 0b00000010000000000100000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- DIVU:
|
DIVU:
|
||||||
|
index: 54
|
||||||
encoding: 0b00000010000000000101000000110011
|
encoding: 0b00000010000000000101000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- REM:
|
REM:
|
||||||
|
index: 55
|
||||||
encoding: 0b00000010000000000110000000110011
|
encoding: 0b00000010000000000110000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- REMU:
|
REMU:
|
||||||
|
index: 56
|
||||||
encoding: 0b00000010000000000111000000110011
|
encoding: 0b00000010000000000111000000110011
|
||||||
mask: 0b11111110000000000111000001111111
|
mask: 0b11111110000000000111000001111111
|
||||||
size: 32
|
size: 32
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
RV32IC:
|
Zca:
|
||||||
- CADDI4SPN:
|
C__ADDI4SPN:
|
||||||
|
index: 57
|
||||||
encoding: 0b0000000000000000
|
encoding: 0b0000000000000000
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CLW:
|
C__LW:
|
||||||
|
index: 58
|
||||||
encoding: 0b0100000000000000
|
encoding: 0b0100000000000000
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSW:
|
C__SW:
|
||||||
|
index: 59
|
||||||
encoding: 0b1100000000000000
|
encoding: 0b1100000000000000
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CADDI:
|
C__ADDI:
|
||||||
|
index: 60
|
||||||
encoding: 0b0000000000000001
|
encoding: 0b0000000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CNOP:
|
C__NOP:
|
||||||
|
index: 61
|
||||||
encoding: 0b0000000000000001
|
encoding: 0b0000000000000001
|
||||||
mask: 0b1110111110000011
|
mask: 0b1110111110000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CJAL:
|
C__JAL:
|
||||||
|
index: 62
|
||||||
encoding: 0b0010000000000001
|
encoding: 0b0010000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
attributes: [[name:no_cont]]
|
attributes: [[name:enable, value:1]]
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: 1
|
||||||
- CLI:
|
C__LI:
|
||||||
|
index: 63
|
||||||
encoding: 0b0100000000000001
|
encoding: 0b0100000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CLUI:
|
C__LUI:
|
||||||
|
index: 64
|
||||||
encoding: 0b0110000000000001
|
encoding: 0b0110000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CADDI16SP:
|
C__ADDI16SP:
|
||||||
|
index: 65
|
||||||
encoding: 0b0110000100000001
|
encoding: 0b0110000100000001
|
||||||
mask: 0b1110111110000011
|
mask: 0b1110111110000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRLI:
|
__reserved_clui:
|
||||||
|
index: 66
|
||||||
|
encoding: 0b0110000000000001
|
||||||
|
mask: 0b1111000001111111
|
||||||
|
size: 16
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
C__SRLI:
|
||||||
|
index: 67
|
||||||
encoding: 0b1000000000000001
|
encoding: 0b1000000000000001
|
||||||
mask: 0b1111110000000011
|
mask: 0b1111110000000011
|
||||||
|
attributes: [[name:enable, value:1]]
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSRAI:
|
C__SRAI:
|
||||||
|
index: 68
|
||||||
encoding: 0b1000010000000001
|
encoding: 0b1000010000000001
|
||||||
mask: 0b1111110000000011
|
mask: 0b1111110000000011
|
||||||
|
attributes: [[name:enable, value:1]]
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CANDI:
|
C__ANDI:
|
||||||
|
index: 69
|
||||||
encoding: 0b1000100000000001
|
encoding: 0b1000100000000001
|
||||||
mask: 0b1110110000000011
|
mask: 0b1110110000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSUB:
|
C__SUB:
|
||||||
|
index: 70
|
||||||
encoding: 0b1000110000000001
|
encoding: 0b1000110000000001
|
||||||
mask: 0b1111110001100011
|
mask: 0b1111110001100011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CXOR:
|
C__XOR:
|
||||||
|
index: 71
|
||||||
encoding: 0b1000110000100001
|
encoding: 0b1000110000100001
|
||||||
mask: 0b1111110001100011
|
mask: 0b1111110001100011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- COR:
|
C__OR:
|
||||||
|
index: 72
|
||||||
encoding: 0b1000110001000001
|
encoding: 0b1000110001000001
|
||||||
mask: 0b1111110001100011
|
mask: 0b1111110001100011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CAND:
|
C__AND:
|
||||||
|
index: 73
|
||||||
encoding: 0b1000110001100001
|
encoding: 0b1000110001100001
|
||||||
mask: 0b1111110001100011
|
mask: 0b1111110001100011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CJ:
|
C__J:
|
||||||
|
index: 74
|
||||||
encoding: 0b1010000000000001
|
encoding: 0b1010000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: 1
|
||||||
- CBEQZ:
|
C__BEQZ:
|
||||||
|
index: 75
|
||||||
encoding: 0b1100000000000001
|
encoding: 0b1100000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- CBNEZ:
|
C__BNEZ:
|
||||||
|
index: 76
|
||||||
encoding: 0b1110000000000001
|
encoding: 0b1110000000000001
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
attributes: [[name:no_cont], [name:cond]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: [1,1]
|
delay: [1,1]
|
||||||
- CSLLI:
|
C__SLLI:
|
||||||
|
index: 77
|
||||||
encoding: 0b0000000000000010
|
encoding: 0b0000000000000010
|
||||||
mask: 0b1111000000000011
|
mask: 0b1111000000000011
|
||||||
|
attributes: [[name:enable, value:1]]
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CLWSP:
|
C__LWSP:
|
||||||
|
index: 78
|
||||||
encoding: 0b0100000000000010
|
encoding: 0b0100000000000010
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CMV:
|
C__MV:
|
||||||
|
index: 79
|
||||||
encoding: 0b1000000000000010
|
encoding: 0b1000000000000010
|
||||||
mask: 0b1111000000000011
|
mask: 0b1111000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CJR:
|
C__JR:
|
||||||
|
index: 80
|
||||||
encoding: 0b1000000000000010
|
encoding: 0b1000000000000010
|
||||||
mask: 0b1111000001111111
|
mask: 0b1111000001111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: 1
|
||||||
- CADD:
|
__reserved_cmv:
|
||||||
|
index: 81
|
||||||
|
encoding: 0b1000000000000010
|
||||||
|
mask: 0b1111111111111111
|
||||||
|
size: 16
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
C__ADD:
|
||||||
|
index: 82
|
||||||
encoding: 0b1001000000000010
|
encoding: 0b1001000000000010
|
||||||
mask: 0b1111000000000011
|
mask: 0b1111000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CJALR:
|
C__JALR:
|
||||||
|
index: 83
|
||||||
encoding: 0b1001000000000010
|
encoding: 0b1001000000000010
|
||||||
mask: 0b1111000001111111
|
mask: 0b1111000001111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: true
|
branch: true
|
||||||
delay: 1
|
delay: 1
|
||||||
- CEBREAK:
|
C__EBREAK:
|
||||||
|
index: 84
|
||||||
encoding: 0b1001000000000010
|
encoding: 0b1001000000000010
|
||||||
mask: 0b1111111111111111
|
mask: 0b1111111111111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- CSWSP:
|
C__SWSP:
|
||||||
|
index: 85
|
||||||
encoding: 0b1100000000000010
|
encoding: 0b1100000000000010
|
||||||
mask: 0b1110000000000011
|
mask: 0b1110000000000011
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
- DII:
|
DII:
|
||||||
|
index: 86
|
||||||
encoding: 0b0000000000000000
|
encoding: 0b0000000000000000
|
||||||
mask: 0b1111111111111111
|
mask: 0b1111111111111111
|
||||||
attributes: [[name:no_cont]]
|
|
||||||
size: 16
|
size: 16
|
||||||
branch: false
|
branch: false
|
||||||
delay: 1
|
delay: 1
|
||||||
@@ -0,0 +1,650 @@
|
|||||||
|
RV32I:
|
||||||
|
ADD:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 51
|
||||||
|
index: 27
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
ADDI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 19
|
||||||
|
index: 18
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
AND:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 28723
|
||||||
|
index: 36
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
ANDI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 28691
|
||||||
|
index: 23
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
AUIPC:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 23
|
||||||
|
index: 1
|
||||||
|
mask: 127
|
||||||
|
size: 32
|
||||||
|
BEQ:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 99
|
||||||
|
index: 4
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
BGE:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 20579
|
||||||
|
index: 7
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
BGEU:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 28771
|
||||||
|
index: 9
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
BLT:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 16483
|
||||||
|
index: 6
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
BLTU:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 24675
|
||||||
|
index: 8
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
BNE:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 4195
|
||||||
|
index: 5
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
EBREAK:
|
||||||
|
attributes:
|
||||||
|
- - name:no_cont
|
||||||
|
branch: false
|
||||||
|
delay: 3
|
||||||
|
encoding: 1048691
|
||||||
|
index: 39
|
||||||
|
mask: 4294967295
|
||||||
|
size: 32
|
||||||
|
ECALL:
|
||||||
|
attributes:
|
||||||
|
- - name:no_cont
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 115
|
||||||
|
index: 38
|
||||||
|
mask: 4294967295
|
||||||
|
size: 32
|
||||||
|
FENCE:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 15
|
||||||
|
index: 37
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
JAL:
|
||||||
|
branch: true
|
||||||
|
delay: 2
|
||||||
|
encoding: 111
|
||||||
|
index: 2
|
||||||
|
mask: 127
|
||||||
|
size: 32
|
||||||
|
JALR:
|
||||||
|
branch: true
|
||||||
|
delay: 2
|
||||||
|
encoding: 103
|
||||||
|
index: 3
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
LB:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 3
|
||||||
|
index: 10
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
LBU:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 16387
|
||||||
|
index: 13
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
LH:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 4099
|
||||||
|
index: 11
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
LHU:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 20483
|
||||||
|
index: 14
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
LUI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 55
|
||||||
|
index: 0
|
||||||
|
mask: 127
|
||||||
|
size: 32
|
||||||
|
LW:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 8195
|
||||||
|
index: 12
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
MRET:
|
||||||
|
attributes:
|
||||||
|
- - name:no_cont
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 807403635
|
||||||
|
index: 40
|
||||||
|
mask: 4294967295
|
||||||
|
size: 32
|
||||||
|
OR:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24627
|
||||||
|
index: 35
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
ORI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24595
|
||||||
|
index: 22
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
SB:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 35
|
||||||
|
index: 15
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
SH:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 4131
|
||||||
|
index: 16
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
SLL:
|
||||||
|
branch: false
|
||||||
|
delay: X_24:20
|
||||||
|
encoding: 4147
|
||||||
|
index: 29
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SLLI:
|
||||||
|
branch: false
|
||||||
|
delay: u_24:20
|
||||||
|
encoding: 4115
|
||||||
|
index: 24
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SLT:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 8243
|
||||||
|
index: 30
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SLTI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 8211
|
||||||
|
index: 19
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
SLTIU:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 12307
|
||||||
|
index: 20
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
SLTU:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 12339
|
||||||
|
index: 31
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SRA:
|
||||||
|
branch: false
|
||||||
|
delay: X_24:20
|
||||||
|
encoding: 1073762355
|
||||||
|
index: 34
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SRAI:
|
||||||
|
branch: false
|
||||||
|
delay: u_24:20
|
||||||
|
encoding: 1073762323
|
||||||
|
index: 26
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SRL:
|
||||||
|
branch: false
|
||||||
|
delay: X_24:20
|
||||||
|
encoding: 20531
|
||||||
|
index: 33
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SRLI:
|
||||||
|
branch: false
|
||||||
|
delay: u_24:20
|
||||||
|
encoding: 20499
|
||||||
|
index: 25
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SUB:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 1073741875
|
||||||
|
index: 28
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
SW:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 8227
|
||||||
|
index: 17
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
WFI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 273678451
|
||||||
|
index: 41
|
||||||
|
mask: 4294967295
|
||||||
|
size: 32
|
||||||
|
XOR:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 16435
|
||||||
|
index: 32
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
XORI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 16403
|
||||||
|
index: 21
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
RV32M:
|
||||||
|
DIV:
|
||||||
|
branch: false
|
||||||
|
delay: 33
|
||||||
|
encoding: 33570867
|
||||||
|
index: 53
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
DIVU:
|
||||||
|
branch: false
|
||||||
|
delay: 33
|
||||||
|
encoding: 33574963
|
||||||
|
index: 54
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
MUL:
|
||||||
|
branch: false
|
||||||
|
delay: 32
|
||||||
|
encoding: 33554483
|
||||||
|
index: 49
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
MULH:
|
||||||
|
branch: false
|
||||||
|
delay: 32
|
||||||
|
encoding: 33558579
|
||||||
|
index: 50
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
MULHSU:
|
||||||
|
branch: false
|
||||||
|
delay: 32
|
||||||
|
encoding: 33562675
|
||||||
|
index: 51
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
MULHU:
|
||||||
|
branch: false
|
||||||
|
delay: 32
|
||||||
|
encoding: 33566771
|
||||||
|
index: 52
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
REM:
|
||||||
|
branch: false
|
||||||
|
delay: 33
|
||||||
|
encoding: 33579059
|
||||||
|
index: 55
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
REMU:
|
||||||
|
branch: false
|
||||||
|
delay: 33
|
||||||
|
encoding: 33583155
|
||||||
|
index: 56
|
||||||
|
mask: 4261441663
|
||||||
|
size: 32
|
||||||
|
Zca:
|
||||||
|
C__ADD:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 36866
|
||||||
|
index: 82
|
||||||
|
mask: 61443
|
||||||
|
size: 16
|
||||||
|
C__ADDI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 1
|
||||||
|
index: 60
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__ADDI16SP:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24833
|
||||||
|
index: 65
|
||||||
|
mask: 61315
|
||||||
|
size: 16
|
||||||
|
C__ADDI4SPN:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 0
|
||||||
|
index: 57
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__AND:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 35937
|
||||||
|
index: 73
|
||||||
|
mask: 64611
|
||||||
|
size: 16
|
||||||
|
C__ANDI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 34817
|
||||||
|
index: 69
|
||||||
|
mask: 60419
|
||||||
|
size: 16
|
||||||
|
C__BEQZ:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 49153
|
||||||
|
index: 75
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__BNEZ:
|
||||||
|
branch: true
|
||||||
|
delay:
|
||||||
|
- 1
|
||||||
|
- 2
|
||||||
|
encoding: 57345
|
||||||
|
index: 76
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__EBREAK:
|
||||||
|
branch: false
|
||||||
|
delay: 3
|
||||||
|
encoding: 36866
|
||||||
|
index: 84
|
||||||
|
mask: 65535
|
||||||
|
size: 16
|
||||||
|
C__J:
|
||||||
|
branch: true
|
||||||
|
delay: 1
|
||||||
|
encoding: 40961
|
||||||
|
index: 74
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__JAL:
|
||||||
|
attributes:
|
||||||
|
- - name:enable
|
||||||
|
- value:1
|
||||||
|
branch: true
|
||||||
|
delay: 1
|
||||||
|
encoding: 8193
|
||||||
|
index: 62
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__JALR:
|
||||||
|
branch: true
|
||||||
|
delay: 1
|
||||||
|
encoding: 36866
|
||||||
|
index: 83
|
||||||
|
mask: 61567
|
||||||
|
size: 16
|
||||||
|
C__JR:
|
||||||
|
branch: true
|
||||||
|
delay: 1
|
||||||
|
encoding: 32770
|
||||||
|
index: 80
|
||||||
|
mask: 61567
|
||||||
|
size: 16
|
||||||
|
C__LI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 16385
|
||||||
|
index: 63
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__LUI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24577
|
||||||
|
index: 64
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__LW:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 16384
|
||||||
|
index: 58
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__LWSP:
|
||||||
|
branch: false
|
||||||
|
delay: 2
|
||||||
|
encoding: 16386
|
||||||
|
index: 78
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__MV:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 32770
|
||||||
|
index: 79
|
||||||
|
mask: 61443
|
||||||
|
size: 16
|
||||||
|
C__NOP:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 1
|
||||||
|
index: 61
|
||||||
|
mask: 61315
|
||||||
|
size: 16
|
||||||
|
C__OR:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 35905
|
||||||
|
index: 72
|
||||||
|
mask: 64611
|
||||||
|
size: 16
|
||||||
|
C__SLLI:
|
||||||
|
attributes:
|
||||||
|
- - name:enable
|
||||||
|
- value:1
|
||||||
|
branch: false
|
||||||
|
delay: u_12:12*16+u_6:2
|
||||||
|
encoding: 2
|
||||||
|
index: 77
|
||||||
|
mask: 61443
|
||||||
|
size: 16
|
||||||
|
C__SRAI:
|
||||||
|
attributes:
|
||||||
|
- - name:enable
|
||||||
|
- value:1
|
||||||
|
branch: false
|
||||||
|
delay: u_12:12*16+u_6:2
|
||||||
|
encoding: 33793
|
||||||
|
index: 68
|
||||||
|
mask: 64515
|
||||||
|
size: 16
|
||||||
|
C__SRLI:
|
||||||
|
attributes:
|
||||||
|
- - name:enable
|
||||||
|
- value:1
|
||||||
|
branch: false
|
||||||
|
delay: u_12:12*16+u_6:2
|
||||||
|
encoding: 32769
|
||||||
|
index: 67
|
||||||
|
mask: 64515
|
||||||
|
size: 16
|
||||||
|
C__SUB:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 35841
|
||||||
|
index: 70
|
||||||
|
mask: 64611
|
||||||
|
size: 16
|
||||||
|
C__SW:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 49152
|
||||||
|
index: 59
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__SWSP:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 49154
|
||||||
|
index: 85
|
||||||
|
mask: 57347
|
||||||
|
size: 16
|
||||||
|
C__XOR:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 35873
|
||||||
|
index: 71
|
||||||
|
mask: 64611
|
||||||
|
size: 16
|
||||||
|
DII:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 0
|
||||||
|
index: 86
|
||||||
|
mask: 65535
|
||||||
|
size: 16
|
||||||
|
__reserved_clui:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24577
|
||||||
|
index: 66
|
||||||
|
mask: 61567
|
||||||
|
size: 16
|
||||||
|
__reserved_cmv:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 32770
|
||||||
|
index: 81
|
||||||
|
mask: 65535
|
||||||
|
size: 16
|
||||||
|
Zicsr:
|
||||||
|
CSRRC:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 12403
|
||||||
|
index: 44
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
CSRRCI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 28787
|
||||||
|
index: 47
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
CSRRS:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 8307
|
||||||
|
index: 43
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
CSRRSI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 24691
|
||||||
|
index: 46
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
CSRRW:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 4211
|
||||||
|
index: 42
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
CSRRWI:
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 20595
|
||||||
|
index: 45
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
|
Zifencei:
|
||||||
|
FENCE_I:
|
||||||
|
attributes:
|
||||||
|
- - name:flush
|
||||||
|
branch: false
|
||||||
|
delay: 1
|
||||||
|
encoding: 4111
|
||||||
|
index: 48
|
||||||
|
mask: 28799
|
||||||
|
size: 32
|
||||||
File renamed without changes.
@@ -19,7 +19,7 @@ setenv CXX $COWAREHOME/SLS/linux/common/bin/g++
|
|||||||
cmake -S . -B build/PA -DCMAKE_BUILD_TYPE=Debug -DUSE_CWR_SYSTEMC=ON -DBUILD_SHARED_LIBS=ON \
|
cmake -S . -B build/PA -DCMAKE_BUILD_TYPE=Debug -DUSE_CWR_SYSTEMC=ON -DBUILD_SHARED_LIBS=ON \
|
||||||
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
||||||
cmake --build build/PA --target install -j16
|
cmake --build build/PA --target install -j16
|
||||||
cd dbt-rise-tgc/contrib
|
cd dbt-rise-tgc/contrib/pa
|
||||||
# import the TGC core itself
|
# import the TGC core itself
|
||||||
pct tgc_import_tb.tcl
|
pct tgc_import_tb.tcl
|
||||||
```
|
```
|
||||||
@@ -37,7 +37,7 @@ export CXX=$COWAREHOME/SLS/linux/common/bin/g++
|
|||||||
cmake -S . -B build/PA -DCMAKE_BUILD_TYPE=Debug -DUSE_CWR_SYSTEMC=ON -DBUILD_SHARED_LIBS=ON \
|
cmake -S . -B build/PA -DCMAKE_BUILD_TYPE=Debug -DUSE_CWR_SYSTEMC=ON -DBUILD_SHARED_LIBS=ON \
|
||||||
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
||||||
cmake --build build/PA --target install -j16
|
cmake --build build/PA --target install -j16
|
||||||
cd dbt-rise-tgc/contrib
|
cd dbt-rise-tgc/contrib/pa
|
||||||
# import the TGC core itself
|
# import the TGC core itself
|
||||||
pct tgc_import_tb.tcl
|
pct tgc_import_tb.tcl
|
||||||
```
|
```
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017 - 2020 MINRES Technologies GmbH
|
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -37,6 +37,7 @@ def getRegisterSizes(){
|
|||||||
return regs
|
return regs
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
// clang-format off
|
||||||
#include "${coreDef.name.toLowerCase()}.h"
|
#include "${coreDef.name.toLowerCase()}.h"
|
||||||
#include "util/ities.h"
|
#include "util/ities.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
@@ -46,10 +47,10 @@ def getRegisterSizes(){
|
|||||||
|
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
|
|
||||||
constexpr std::array<const char*, ${registers.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
|
constexpr std::array<const char*, ${registers.size()}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
|
||||||
constexpr std::array<const char*, ${registers.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
|
constexpr std::array<const char*, ${registers.size()}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
|
||||||
constexpr std::array<const uint32_t, ${getRegisterSizes().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
|
constexpr std::array<const uint32_t, ${getRegisterSizes().size()}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
|
||||||
constexpr std::array<const uint32_t, ${getRegisterSizes().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
|
constexpr std::array<const uint32_t, ${getRegisterSizes().size()}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
|
||||||
|
|
||||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() = default;
|
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() = default;
|
||||||
|
|
||||||
@@ -73,4 +74,4 @@ uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() {
|
|||||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &addr) {
|
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &addr) {
|
||||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017 - 2021 MINRES Technologies GmbH
|
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -60,7 +60,7 @@ def getCString(def val){
|
|||||||
%>
|
%>
|
||||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||||
#define _${coreDef.name.toUpperCase()}_H_
|
#define _${coreDef.name.toUpperCase()}_H_
|
||||||
|
// clang-format off
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
@@ -75,11 +75,11 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
|||||||
|
|
||||||
constexpr static char const* const core_type = "${coreDef.name}";
|
constexpr static char const* const core_type = "${coreDef.name}";
|
||||||
|
|
||||||
static constexpr std::array<const char*, ${registers.size}> reg_names{
|
static constexpr std::array<const char*, ${registers.size()}> reg_names{
|
||||||
{"${registers.collect{it.name}.join('", "')}"}};
|
{"${registers.collect{it.name.toLowerCase()}.join('", "')}"}};
|
||||||
|
|
||||||
static constexpr std::array<const char*, ${registers.size}> reg_aliases{
|
static constexpr std::array<const char*, ${registers.size()}> reg_aliases{
|
||||||
{"${registers.collect{it.alias}.join('", "')}"}};
|
{"${registers.collect{it.alias.toLowerCase()}.join('", "')}"}};
|
||||||
|
|
||||||
enum constants {${constants.collect{c -> c.name+"="+getCString(c.value)}.join(', ')}};
|
enum constants {${constants.collect{c -> c.name+"="+getCString(c.value)}.join(', ')}};
|
||||||
|
|
||||||
@@ -99,17 +99,17 @@ template <> struct traits<${coreDef.name.toLowerCase()}> {
|
|||||||
|
|
||||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||||
|
|
||||||
static constexpr std::array<const uint32_t, ${getRegisterSizes().size}> reg_bit_widths{
|
static constexpr std::array<const uint32_t, ${getRegisterSizes().size()}> reg_bit_widths{
|
||||||
{${getRegisterSizes().join(',')}}};
|
{${getRegisterSizes().join(',')}}};
|
||||||
|
|
||||||
static constexpr std::array<const uint32_t, ${getRegisterOffsets().size}> reg_byte_offsets{
|
static constexpr std::array<const uint32_t, ${getRegisterOffsets().size()}> reg_byte_offsets{
|
||||||
{${getRegisterOffsets().join(',')}}};
|
{${getRegisterOffsets().join(',')}}};
|
||||||
|
|
||||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||||
|
|
||||||
enum sreg_flag_e { FLAGS };
|
enum sreg_flag_e { FLAGS };
|
||||||
|
|
||||||
enum mem_type_e { ${spaces.collect{it.name}.join(', ')} };
|
enum mem_type_e { ${spaces.collect{it.name}.join(', ')}, IMEM = MEM };
|
||||||
|
|
||||||
enum class opcode_e {<%instructions.eachWithIndex{instr, index -> %>
|
enum class opcode_e {<%instructions.eachWithIndex{instr, index -> %>
|
||||||
${instr.instruction.name} = ${index},<%}%>
|
${instr.instruction.name} = ${index},<%}%>
|
||||||
@@ -131,8 +131,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
|||||||
|
|
||||||
uint8_t* get_regs_base_ptr() override;
|
uint8_t* get_regs_base_ptr() override;
|
||||||
|
|
||||||
inline uint64_t get_icount() { return reg.icount; }
|
|
||||||
|
|
||||||
inline bool should_stop() { return interrupt_sim; }
|
inline bool should_stop() { return interrupt_sim; }
|
||||||
|
|
||||||
inline uint64_t stop_code() { return interrupt_sim; }
|
inline uint64_t stop_code() { return interrupt_sim; }
|
||||||
@@ -141,8 +139,6 @@ struct ${coreDef.name.toLowerCase()}: public arch_if {
|
|||||||
|
|
||||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||||
|
|
||||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
struct ${coreDef.name}_regs {<%
|
struct ${coreDef.name}_regs {<%
|
||||||
@@ -174,3 +170,4 @@ if(fcsr != null) {%>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
||||||
|
// clang-format on
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#include "${coreDef.name.toLowerCase()}.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace iss {
|
|
||||||
namespace arch {
|
|
||||||
namespace {
|
|
||||||
// according to
|
|
||||||
// https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation
|
|
||||||
#ifdef __GCC__
|
|
||||||
constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); }
|
|
||||||
#elif __cplusplus < 201402L
|
|
||||||
constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); }
|
|
||||||
constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; }
|
|
||||||
#else
|
|
||||||
constexpr size_t bit_count(uint32_t u) {
|
|
||||||
size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
|
|
||||||
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* start opcode definitions
|
|
||||||
****************************************************************************/
|
|
||||||
struct instruction_desriptor {
|
|
||||||
size_t length;
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t mask;
|
|
||||||
opcode_e op;
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::array<instruction_desriptor, ${instructions.size}> instr_descr = {{
|
|
||||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
|
||||||
{${instr.length}, ${instr.encoding}, ${instr.mask}, opcode_e::${instr.instruction.name}},<%}%>
|
|
||||||
}};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct instruction_decoder<${coreDef.name.toLowerCase()}> {
|
|
||||||
using opcode_e = traits<${coreDef.name.toLowerCase()}>::opcode_e;
|
|
||||||
using code_word_t=traits<${coreDef.name.toLowerCase()}>::code_word_t;
|
|
||||||
|
|
||||||
struct instruction_pattern {
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t mask;
|
|
||||||
opcode_e id;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<std::vector<instruction_pattern>, 4> qlut;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
unsigned decode_instruction(T);
|
|
||||||
|
|
||||||
instruction_decoder() {
|
|
||||||
for (auto instr : instr_descr) {
|
|
||||||
auto quadrant = instr.value & 0x3;
|
|
||||||
qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op});
|
|
||||||
}
|
|
||||||
for(auto& lut: qlut){
|
|
||||||
std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){
|
|
||||||
return bit_count(a.mask) < bit_count(b.mask);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
unsigned instruction_decoder<${coreDef.name.toLowerCase()}>::decode_instruction<traits<${coreDef.name.toLowerCase()}>::code_word_t>(traits<${coreDef.name.toLowerCase()}>::code_word_t instr){
|
|
||||||
auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){
|
|
||||||
return !((instr&e.mask) ^ e.value );
|
|
||||||
});
|
|
||||||
return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<instruction_decoder<${coreDef.name.toLowerCase()}>> traits<${coreDef.name.toLowerCase()}>::get_decoder(){
|
|
||||||
return std::make_unique<instruction_decoder<${coreDef.name.toLowerCase()}>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,9 +8,10 @@
|
|||||||
instrGroups[groupName]+=it;
|
instrGroups[groupName]+=it;
|
||||||
}
|
}
|
||||||
instrGroups
|
instrGroups
|
||||||
}%><%getInstructionGroups().each{name, instrList -> %>
|
}%><%int index = 0; getInstructionGroups().each{name, instrList -> %>
|
||||||
${name}: <% instrList.findAll{!it.instruction.name.startsWith("__")}.each { %>
|
${name}: <% instrList.each { %>
|
||||||
- ${it.instruction.name}:
|
${it.instruction.name}:
|
||||||
|
index: ${index++}
|
||||||
encoding: ${it.encoding}
|
encoding: ${it.encoding}
|
||||||
mask: ${it.mask}<%if(it.attributes.size) {%>
|
mask: ${it.mask}<%if(it.attributes.size) {%>
|
||||||
attributes: ${it.attributes}<%}%>
|
attributes: ${it.attributes}<%}%>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2023 MINRES Technologies GmbH
|
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -29,46 +29,103 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include "iss_factory.h"
|
#include <sysc/iss_factory.h>
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
#include <iss/arch/riscv_hart_mu_p.h>
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
#include "sc_core_adapter.h"
|
#include <sysc/sc_core_adapter.h>
|
||||||
#include "core_complex.h"
|
#include <sysc/core_complex.h>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
<%
|
||||||
|
def array_count = coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e"? 3 : 2;
|
||||||
|
%>
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace interp {
|
namespace interp {
|
||||||
using namespace sysc;
|
using namespace sysc;
|
||||||
volatile std::array<bool, 2> ${coreDef.name.toLowerCase()}_init = {
|
volatile std::array<bool, ${array_count}> ${coreDef.name.toLowerCase()}_init = {
|
||||||
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
}),
|
}),
|
||||||
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
})
|
})<%if(coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e") {%>,
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p_clic_pmp|interp", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_EXT_N | iss::arch::FEAT_CLIC)>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%}%>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
#if defined(WITH_LLVM)
|
||||||
|
namespace llvm {
|
||||||
|
using namespace sysc;
|
||||||
|
volatile std::array<bool, ${array_count}> ${coreDef.name.toLowerCase()}_init = {
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
}),
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%if(coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e") {%>,
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p_clic_pmp|llvm", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_EXT_N | iss::arch::FEAT_CLIC)>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%}%>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(WITH_TCC)
|
#if defined(WITH_TCC)
|
||||||
namespace tcc {
|
namespace tcc {
|
||||||
using namespace sysc;
|
using namespace sysc;
|
||||||
volatile std::array<bool, 2> ${coreDef.name.toLowerCase()}_init = {
|
volatile std::array<bool, ${array_count}> ${coreDef.name.toLowerCase()}_init = {
|
||||||
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
}),
|
}),
|
||||||
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
auto* cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
})
|
})<%if(coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e") {%>,
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p_clic_pmp|tcc", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_EXT_N | iss::arch::FEAT_CLIC)>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%}%>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(WITH_ASMJIT)
|
||||||
|
namespace asmjit {
|
||||||
|
using namespace sysc;
|
||||||
|
volatile std::array<bool, ${array_count}> ${coreDef.name.toLowerCase()}_init = {
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_m_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
}),
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%if(coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e") {%>,
|
||||||
|
iss_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p_clic_pmp|asmjit", [](unsigned gdb_port, void* data) -> iss_factory::base_t {
|
||||||
|
auto* cc = reinterpret_cast<sysc::tgfs::core_complex_if*>(data);
|
||||||
|
auto* cpu = new sc_core_adapter<arch::riscv_hart_mu_p<arch::${coreDef.name.toLowerCase()}, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_EXT_N | iss::arch::FEAT_CLIC)>>(cc);
|
||||||
|
return {sysc::sc_cpu_ptr{cpu}, vm_ptr{create(static_cast<arch::${coreDef.name.toLowerCase()}*>(cpu), gdb_port)}};
|
||||||
|
})<%}%>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -0,0 +1,371 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (C) 2017-2024 MINRES Technologies GmbH
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
|
#include <iss/debugger/gdb_session.h>
|
||||||
|
#include <iss/debugger/server.h>
|
||||||
|
#include <iss/iss.h>
|
||||||
|
#include <iss/asmjit/vm_base.h>
|
||||||
|
#include <asmjit/asmjit.h>
|
||||||
|
#include <util/logging.h>
|
||||||
|
#include <iss/instruction_decoder.h>
|
||||||
|
<%def fcsr = registers.find {it.name=='FCSR'}
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
#include <vm/fp_functions.h><%}%>
|
||||||
|
#ifndef FMT_HEADER_ONLY
|
||||||
|
#define FMT_HEADER_ONLY
|
||||||
|
#endif
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <iss/debugger/riscv_target_adapter.h>
|
||||||
|
|
||||||
|
namespace iss {
|
||||||
|
namespace asmjit {
|
||||||
|
|
||||||
|
|
||||||
|
namespace ${coreDef.name.toLowerCase()} {
|
||||||
|
using namespace ::asmjit;
|
||||||
|
using namespace iss::arch;
|
||||||
|
using namespace iss::debugger;
|
||||||
|
|
||||||
|
template <typename ARCH> class vm_impl : public iss::asmjit::vm_base<ARCH> {
|
||||||
|
public:
|
||||||
|
using traits = arch::traits<ARCH>;
|
||||||
|
using super = typename iss::asmjit::vm_base<ARCH>;
|
||||||
|
using virt_addr_t = typename super::virt_addr_t;
|
||||||
|
using phys_addr_t = typename super::phys_addr_t;
|
||||||
|
using code_word_t = typename super::code_word_t;
|
||||||
|
using mem_type_e = typename super::mem_type_e;
|
||||||
|
using addr_t = typename super::addr_t;
|
||||||
|
|
||||||
|
vm_impl();
|
||||||
|
|
||||||
|
vm_impl(ARCH &core, unsigned core_id = 0, unsigned cluster_id = 0);
|
||||||
|
|
||||||
|
void enableDebug(bool enable) { super::sync_exec = super::ALL_SYNC; }
|
||||||
|
|
||||||
|
target_adapter_if *accquire_target_adapter(server_if *srv) override {
|
||||||
|
debugger_if::dbg_enabled = true;
|
||||||
|
if (vm_base<ARCH>::tgt_adapter == nullptr)
|
||||||
|
vm_base<ARCH>::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
||||||
|
return vm_base<ARCH>::tgt_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
using super::get_ptr_for;
|
||||||
|
using super::get_reg_for;
|
||||||
|
using super::get_reg_for_Gp;
|
||||||
|
using super::load_reg_from_mem;
|
||||||
|
using super::load_reg_from_mem_Gp;
|
||||||
|
using super::write_reg_to_mem;
|
||||||
|
using super::gen_read_mem;
|
||||||
|
using super::gen_write_mem;
|
||||||
|
using super::gen_leave;
|
||||||
|
using super::gen_sync;
|
||||||
|
|
||||||
|
using this_class = vm_impl<ARCH>;
|
||||||
|
using compile_func = continuation_e (this_class::*)(virt_addr_t&, code_word_t, jit_holder&);
|
||||||
|
|
||||||
|
continuation_e gen_single_inst_behavior(virt_addr_t&, unsigned int &, jit_holder&) override;
|
||||||
|
enum globals_e {TVAL = 0, GLOBALS_SIZE};
|
||||||
|
void gen_block_prologue(jit_holder& jh) override;
|
||||||
|
void gen_block_epilogue(jit_holder& jh) override;
|
||||||
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
<%if(fcsr != null) {%>
|
||||||
|
inline const char *fname(size_t index){return index < 32?name(index+traits::F0):"illegal";}
|
||||||
|
<%}%>
|
||||||
|
void gen_instr_prologue(jit_holder& jh);
|
||||||
|
void gen_instr_epilogue(jit_holder& jh);
|
||||||
|
inline void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause);
|
||||||
|
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type> void gen_set_tval(jit_holder& jh, T new_tval) ;
|
||||||
|
void gen_set_tval(jit_holder& jh, x86_reg_t _new_tval) ;
|
||||||
|
|
||||||
|
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||||
|
inline S sext(U from) {
|
||||||
|
auto mask = (1ULL<<W) - 1;
|
||||||
|
auto sign_mask = 1ULL<<(W-1);
|
||||||
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
|
}
|
||||||
|
<%functions.each{ it.eachLine { %>
|
||||||
|
${it}<%}%>
|
||||||
|
<%}%>
|
||||||
|
private:
|
||||||
|
/****************************************************************************
|
||||||
|
* start opcode definitions
|
||||||
|
****************************************************************************/
|
||||||
|
struct instruction_descriptor {
|
||||||
|
uint32_t length;
|
||||||
|
uint32_t value;
|
||||||
|
uint32_t mask;
|
||||||
|
compile_func op;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<instruction_descriptor, ${instructions.size()}> instr_descr = {{
|
||||||
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
|
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
||||||
|
{${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||||
|
}};
|
||||||
|
|
||||||
|
//needs to be declared after instr_descr
|
||||||
|
decoder instr_decoder;
|
||||||
|
|
||||||
|
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
|
/* instruction ${idx}: ${instr.name} */
|
||||||
|
continuation_e __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, jit_holder& jh){
|
||||||
|
uint64_t PC = pc.val;
|
||||||
|
<%instr.fields.eachLine{%>${it}
|
||||||
|
<%}%>if(this->disass_enabled){
|
||||||
|
/* generate disass */
|
||||||
|
<%instr.disass.eachLine{%>
|
||||||
|
${it}<%}%>
|
||||||
|
InvokeNode* call_print_disass;
|
||||||
|
char* mnemonic_ptr = strdup(mnemonic.c_str());
|
||||||
|
jh.disass_collection.push_back(mnemonic_ptr);
|
||||||
|
jh.cc.invoke(&call_print_disass, &print_disass, FuncSignature::build<void, void *, uint64_t, char *>());
|
||||||
|
call_print_disass->setArg(0, jh.arch_if_ptr);
|
||||||
|
call_print_disass->setArg(1, pc.val);
|
||||||
|
call_print_disass->setArg(2, mnemonic_ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
x86::Compiler& cc = jh.cc;
|
||||||
|
cc.comment(fmt::format("${instr.name}_{:#x}:",pc.val).c_str());
|
||||||
|
gen_sync(jh, PRE_SYNC, ${idx});
|
||||||
|
mov(cc, jh.pc, pc.val);
|
||||||
|
gen_set_tval(jh, instr);
|
||||||
|
pc = pc+${instr.length/8};
|
||||||
|
mov(cc, jh.next_pc, pc.val);
|
||||||
|
|
||||||
|
gen_instr_prologue(jh);
|
||||||
|
cc.comment("//behavior:");
|
||||||
|
/*generate behavior*/
|
||||||
|
<%instr.behavior.eachLine{%>${it}
|
||||||
|
<%}%>
|
||||||
|
gen_sync(jh, POST_SYNC, ${idx});
|
||||||
|
gen_instr_epilogue(jh);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
<%}%>
|
||||||
|
/****************************************************************************
|
||||||
|
* end opcode definitions
|
||||||
|
****************************************************************************/
|
||||||
|
continuation_e illegal_instruction(virt_addr_t &pc, code_word_t instr, jit_holder& jh ) {
|
||||||
|
x86::Compiler& cc = jh.cc;
|
||||||
|
if(this->disass_enabled){
|
||||||
|
auto mnemonic = std::string("illegal_instruction");
|
||||||
|
InvokeNode* call_print_disass;
|
||||||
|
char* mnemonic_ptr = strdup(mnemonic.c_str());
|
||||||
|
jh.disass_collection.push_back(mnemonic_ptr);
|
||||||
|
jh.cc.invoke(&call_print_disass, &print_disass, FuncSignature::build<void, void *, uint64_t, char *>());
|
||||||
|
call_print_disass->setArg(0, jh.arch_if_ptr);
|
||||||
|
call_print_disass->setArg(1, pc.val);
|
||||||
|
call_print_disass->setArg(2, mnemonic_ptr);
|
||||||
|
}
|
||||||
|
cc.comment(fmt::format("illegal_instruction{:#x}:",pc.val).c_str());
|
||||||
|
gen_sync(jh, PRE_SYNC, instr_descr.size());
|
||||||
|
mov(cc, jh.pc, pc.val);
|
||||||
|
gen_set_tval(jh, instr);
|
||||||
|
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
|
mov(cc, jh.next_pc, pc.val);
|
||||||
|
gen_instr_prologue(jh);
|
||||||
|
cc.comment("//behavior:");
|
||||||
|
gen_raise(jh, 0, 2);
|
||||||
|
gen_sync(jh, POST_SYNC, instr_descr.size());
|
||||||
|
gen_instr_epilogue(jh);
|
||||||
|
return ILLEGAL_INSTR;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
||||||
|
|
||||||
|
template <typename ARCH>
|
||||||
|
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
|
: vm_base<ARCH>(core, core_id, cluster_id)
|
||||||
|
, instr_decoder([this]() {
|
||||||
|
std::vector<generic_instruction_descriptor> g_instr_descr;
|
||||||
|
g_instr_descr.reserve(instr_descr.size());
|
||||||
|
for (uint32_t i = 0; i < instr_descr.size(); ++i) {
|
||||||
|
generic_instruction_descriptor new_instr_descr {instr_descr[i].value, instr_descr[i].mask, i};
|
||||||
|
g_instr_descr.push_back(new_instr_descr);
|
||||||
|
}
|
||||||
|
return std::move(g_instr_descr);
|
||||||
|
}()) {}
|
||||||
|
|
||||||
|
template <typename ARCH>
|
||||||
|
continuation_e vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, jit_holder& jh) {
|
||||||
|
enum {TRAP_ID=1<<16};
|
||||||
|
code_word_t instr = 0;
|
||||||
|
phys_addr_t paddr(pc);
|
||||||
|
auto *const data = (uint8_t *)&instr;
|
||||||
|
if(this->core.has_mmu())
|
||||||
|
paddr = this->core.virt2phys(pc);
|
||||||
|
auto res = this->core.read(paddr, 4, data);
|
||||||
|
if (res != iss::Ok)
|
||||||
|
return ILLEGAL_FETCH;
|
||||||
|
if (instr == 0x0000006f || (instr&0xffff)==0xa001)
|
||||||
|
return JUMP_TO_SELF;
|
||||||
|
++inst_cnt;
|
||||||
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
||||||
|
compile_func f = nullptr;
|
||||||
|
if(inst_index < instr_descr.size())
|
||||||
|
f = instr_descr[inst_index].op;
|
||||||
|
if (f == nullptr)
|
||||||
|
f = &this_class::illegal_instruction;
|
||||||
|
return (this->*f)(pc, instr, jh);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_instr_prologue(jit_holder& jh) {
|
||||||
|
auto& cc = jh.cc;
|
||||||
|
|
||||||
|
cc.comment("//gen_instr_prologue");
|
||||||
|
|
||||||
|
x86_reg_t current_trap_state = get_reg_for(cc, traits::TRAP_STATE);
|
||||||
|
mov(cc, current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||||
|
mov(cc, get_ptr_for(jh, traits::PENDING_TRAP), current_trap_state);
|
||||||
|
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_instr_epilogue(jit_holder& jh) {
|
||||||
|
auto& cc = jh.cc;
|
||||||
|
|
||||||
|
cc.comment("//gen_instr_epilogue");
|
||||||
|
x86_reg_t current_trap_state = get_reg_for(cc, traits::TRAP_STATE);
|
||||||
|
mov(cc, current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||||
|
cmp(cc, current_trap_state, 0);
|
||||||
|
cc.jne(jh.trap_entry);
|
||||||
|
cc.inc(get_ptr_for(jh, traits::ICOUNT));
|
||||||
|
cc.inc(get_ptr_for(jh, traits::CYCLE));
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_block_prologue(jit_holder& jh){
|
||||||
|
jh.pc = load_reg_from_mem_Gp(jh, traits::PC);
|
||||||
|
jh.next_pc = load_reg_from_mem_Gp(jh, traits::NEXT_PC);
|
||||||
|
jh.globals.resize(GLOBALS_SIZE);
|
||||||
|
jh.globals[TVAL] = get_reg_Gp(jh.cc, 64, false);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_block_epilogue(jit_holder& jh){
|
||||||
|
x86::Compiler& cc = jh.cc;
|
||||||
|
cc.comment("//gen_block_epilogue");
|
||||||
|
cc.ret(jh.next_pc);
|
||||||
|
|
||||||
|
cc.bind(jh.trap_entry);
|
||||||
|
this->write_back(jh);
|
||||||
|
|
||||||
|
x86::Gp current_trap_state = get_reg_for_Gp(cc, traits::TRAP_STATE);
|
||||||
|
mov(cc, current_trap_state, get_ptr_for(jh, traits::TRAP_STATE));
|
||||||
|
|
||||||
|
x86::Gp current_pc = get_reg_for_Gp(cc, traits::PC);
|
||||||
|
mov(cc, current_pc, get_ptr_for(jh, traits::PC));
|
||||||
|
|
||||||
|
cc.comment("//enter trap call;");
|
||||||
|
InvokeNode* call_enter_trap;
|
||||||
|
cc.invoke(&call_enter_trap, &enter_trap, FuncSignature::build<uint64_t, void*, uint64_t, uint64_t, uint64_t>());
|
||||||
|
call_enter_trap->setArg(0, jh.arch_if_ptr);
|
||||||
|
call_enter_trap->setArg(1, current_trap_state);
|
||||||
|
call_enter_trap->setArg(2, current_pc);
|
||||||
|
call_enter_trap->setArg(3, jh.globals[TVAL]);
|
||||||
|
|
||||||
|
x86_reg_t current_next_pc = get_reg_for(cc, traits::NEXT_PC);
|
||||||
|
mov(cc, current_next_pc, get_ptr_for(jh, traits::NEXT_PC));
|
||||||
|
mov(cc, jh.next_pc, current_next_pc);
|
||||||
|
|
||||||
|
mov(cc, get_ptr_for(jh, traits::LAST_BRANCH), static_cast<int>(UNKNOWN_JUMP));
|
||||||
|
cc.ret(jh.next_pc);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
inline void vm_impl<ARCH>::gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) {
|
||||||
|
auto& cc = jh.cc;
|
||||||
|
cc.comment("//gen_raise");
|
||||||
|
auto tmp1 = get_reg_for(cc, traits::TRAP_STATE);
|
||||||
|
mov(cc, tmp1, 0x80ULL << 24 | (cause << 16) | trap_id);
|
||||||
|
mov(cc, get_ptr_for(jh, traits::TRAP_STATE), tmp1);
|
||||||
|
cc.jmp(jh.trap_entry);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
template <typename T, typename>
|
||||||
|
void vm_impl<ARCH>::gen_set_tval(jit_holder& jh, T new_tval) {
|
||||||
|
mov(jh.cc, jh.globals[TVAL], new_tval);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_set_tval(jit_holder& jh, x86_reg_t _new_tval) {
|
||||||
|
if(nonstd::holds_alternative<x86::Gp>(_new_tval)) {
|
||||||
|
x86::Gp new_tval = nonstd::get<x86::Gp>(_new_tval);
|
||||||
|
if(new_tval.size() < 8)
|
||||||
|
new_tval = gen_ext_Gp(jh.cc, new_tval, 64, false);
|
||||||
|
mov(jh.cc, jh.globals[TVAL], new_tval);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Variant not supported in gen_set_tval");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tgc5c
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreDef.name.toLowerCase()} *core, unsigned short port, bool dump) {
|
||||||
|
auto ret = new ${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*core, dump);
|
||||||
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret, port);
|
||||||
|
return std::unique_ptr<vm_if>(ret);
|
||||||
|
}
|
||||||
|
} // namespace asmjit
|
||||||
|
} // namespace iss
|
||||||
|
|
||||||
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
|
#include <iss/factory.h>
|
||||||
|
namespace iss {
|
||||||
|
namespace {
|
||||||
|
volatile std::array<bool, 2> dummy = {
|
||||||
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|asmjit", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
|
auto vm = new asmjit::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
|
}),
|
||||||
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|asmjit", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
|
auto vm = new asmjit::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2021 MINRES Technologies GmbH
|
* Copyright (C) 2017-2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -34,15 +34,22 @@ def nativeTypeSize(int size){
|
|||||||
if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
|
if(size<=8) return 8; else if(size<=16) return 16; else if(size<=32) return 32; else return 64;
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
|
// clang-format off
|
||||||
|
#include <cstdint>
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
#include <iss/iss.h>
|
#include <iss/iss.h>
|
||||||
#include <iss/interp/vm_base.h>
|
#include <iss/interp/vm_base.h>
|
||||||
|
#include <vm/fp_functions.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <sstream>
|
|
||||||
#include <boost/coroutine2/all.hpp>
|
#include <boost/coroutine2/all.hpp>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <exception>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iss/instruction_decoder.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
@@ -59,6 +66,10 @@ using namespace iss::arch;
|
|||||||
using namespace iss::debugger;
|
using namespace iss::debugger;
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
struct memory_access_exception : public std::exception{
|
||||||
|
memory_access_exception(){}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
|
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
|
||||||
public:
|
public:
|
||||||
using traits = arch::traits<ARCH>;
|
using traits = arch::traits<ARCH>;
|
||||||
@@ -89,37 +100,20 @@ protected:
|
|||||||
using compile_ret_t = virt_addr_t;
|
using compile_ret_t = virt_addr_t;
|
||||||
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr);
|
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr);
|
||||||
|
|
||||||
inline const char *name(size_t index){return index<traits::reg_aliases.size()?traits::reg_aliases[index]:"illegal";}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
<%
|
||||||
|
def fcsr = registers.find {it.name=='FCSR'}
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
inline const char *fname(size_t index){return index < 32?name(index+traits::F0):"illegal";}
|
||||||
|
<%}%>
|
||||||
|
|
||||||
typename arch::traits<ARCH>::opcode_e decode_inst_id(code_word_t instr);
|
|
||||||
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
virt_addr_t execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit) override;
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
|
||||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
|
||||||
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
|
|
||||||
enum {
|
|
||||||
LUT_SIZE = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK32)),
|
|
||||||
LUT_SIZE_C = 1 << util::bit_count(static_cast<uint32_t>(EXTR_MASK16))
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<compile_func, LUT_SIZE> lut;
|
|
||||||
|
|
||||||
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
|
||||||
std::array<compile_func, LUT_SIZE> lut_11;
|
|
||||||
|
|
||||||
struct instruction_pattern {
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t mask;
|
|
||||||
typename arch::traits<ARCH>::opcode_e id;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<std::vector<instruction_pattern>, 4> qlut;
|
|
||||||
|
|
||||||
inline void raise(uint16_t trap_id, uint16_t cause){
|
inline void raise(uint16_t trap_id, uint16_t cause){
|
||||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||||
this->core.reg.trap_state = trap_val;
|
this->core.reg.trap_state = trap_val;
|
||||||
this->template get_reg<uint${addrDataWidth}_t>(traits::NEXT_PC) = std::numeric_limits<uint${addrDataWidth}_t>::max();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void leave(unsigned lvl){
|
inline void leave(unsigned lvl){
|
||||||
@@ -130,6 +124,13 @@ protected:
|
|||||||
this->core.wait_until(type);
|
this->core.wait_until(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void set_tval(uint64_t new_tval){
|
||||||
|
tval = new_tval;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t fetch_count{0};
|
||||||
|
uint64_t tval{0};
|
||||||
|
|
||||||
using yield_t = boost::coroutines2::coroutine<void>::push_type;
|
using yield_t = boost::coroutines2::coroutine<void>::push_type;
|
||||||
using coro_t = boost::coroutines2::coroutine<void>::pull_type;
|
using coro_t = boost::coroutines2::coroutine<void>::pull_type;
|
||||||
std::vector<coro_t> spawn_blocks;
|
std::vector<coro_t> spawn_blocks;
|
||||||
@@ -159,25 +160,20 @@ private:
|
|||||||
* start opcode definitions
|
* start opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct instruction_descriptor {
|
struct instruction_descriptor {
|
||||||
size_t length;
|
uint32_t length;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
typename arch::traits<ARCH>::opcode_e op;
|
typename arch::traits<ARCH>::opcode_e op;
|
||||||
};
|
};
|
||||||
struct decoding_tree_node{
|
|
||||||
std::vector<instruction_descriptor> instrs;
|
|
||||||
std::vector<decoding_tree_node*> children;
|
|
||||||
uint32_t submask = std::numeric_limits<uint32_t>::max();
|
|
||||||
uint32_t value;
|
|
||||||
decoding_tree_node(uint32_t value) : value(value){}
|
|
||||||
};
|
|
||||||
|
|
||||||
decoding_tree_node* root {nullptr};
|
const std::array<instruction_descriptor, ${instructions.size()}> instr_descr = {{
|
||||||
const std::array<instruction_descriptor, ${instructions.size}> instr_descr = {{
|
|
||||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
{${instr.length}, ${instr.encoding}, ${instr.mask}, arch::traits<ARCH>::opcode_e::${instr.instruction.name}},<%}%>
|
{${instr.length}, ${instr.encoding}, ${instr.mask}, arch::traits<ARCH>::opcode_e::${instr.instruction.name}},<%}%>
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
//needs to be declared after instr_descr
|
||||||
|
decoder instr_decoder;
|
||||||
|
|
||||||
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
|
||||||
if(this->core.has_mmu()) {
|
if(this->core.has_mmu()) {
|
||||||
auto phys_pc = this->core.virt2phys(pc);
|
auto phys_pc = this->core.virt2phys(pc);
|
||||||
@@ -197,57 +193,6 @@ private:
|
|||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populate_decoding_tree(decoding_tree_node* root){
|
|
||||||
//create submask
|
|
||||||
for(auto instr: root->instrs){
|
|
||||||
root->submask &= instr.mask;
|
|
||||||
}
|
|
||||||
//put each instr according to submask&encoding into children
|
|
||||||
for(auto instr: root->instrs){
|
|
||||||
bool foundMatch = false;
|
|
||||||
for(auto child: root->children){
|
|
||||||
//use value as identifying trait
|
|
||||||
if(child->value == (instr.value&root->submask)){
|
|
||||||
child->instrs.push_back(instr);
|
|
||||||
foundMatch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!foundMatch){
|
|
||||||
decoding_tree_node* child = new decoding_tree_node(instr.value&root->submask);
|
|
||||||
child->instrs.push_back(instr);
|
|
||||||
root->children.push_back(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
root->instrs.clear();
|
|
||||||
//call populate_decoding_tree for all children
|
|
||||||
if(root->children.size() >1)
|
|
||||||
for(auto child: root->children){
|
|
||||||
populate_decoding_tree(child);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
//sort instrs by value of the mask, this works bc we want to have the least restrictive one last
|
|
||||||
std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) {
|
|
||||||
return instr1.mask > instr2.mask;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
typename arch::traits<ARCH>::opcode_e decode_instr(decoding_tree_node* node, code_word_t word){
|
|
||||||
if(!node->children.size()){
|
|
||||||
if(node->instrs.size() == 1) return node->instrs[0].op;
|
|
||||||
for(auto instr : node->instrs){
|
|
||||||
if((instr.mask&word) == instr.value) return instr.op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for(auto child : node->children){
|
|
||||||
if (child->value == (node->submask&word)){
|
|
||||||
return decode_instr(child, word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return arch::traits<ARCH>::opcode_e::MAX_OPCODE;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
||||||
@@ -273,16 +218,23 @@ constexpr size_t bit_count(uint32_t u) {
|
|||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
: vm_base<ARCH>(core, core_id, cluster_id) {
|
: vm_base<ARCH>(core, core_id, cluster_id)
|
||||||
root = new decoding_tree_node(std::numeric_limits<uint32_t>::max());
|
, instr_decoder([this]() {
|
||||||
for(auto instr:instr_descr){
|
std::vector<generic_instruction_descriptor> g_instr_descr;
|
||||||
root->instrs.push_back(instr);
|
g_instr_descr.reserve(instr_descr.size());
|
||||||
|
for (uint32_t i = 0; i < instr_descr.size(); ++i) {
|
||||||
|
generic_instruction_descriptor new_instr_descr {instr_descr[i].value, instr_descr[i].mask, i};
|
||||||
|
g_instr_descr.push_back(new_instr_descr);
|
||||||
}
|
}
|
||||||
populate_decoding_tree(root);
|
return std::move(g_instr_descr);
|
||||||
|
}()) {}
|
||||||
|
|
||||||
|
inline bool is_icount_limit_enabled(finish_cond_e cond){
|
||||||
|
return (cond & finish_cond_e::ICOUNT_LIMIT) == finish_cond_e::ICOUNT_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_count_limit_enabled(finish_cond_e cond){
|
inline bool is_fcount_limit_enabled(finish_cond_e cond){
|
||||||
return (cond & finish_cond_e::COUNT_LIMIT) == finish_cond_e::COUNT_LIMIT;
|
return (cond & finish_cond_e::FCOUNT_LIMIT) == finish_cond_e::FCOUNT_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_jump_to_self_enabled(finish_cond_e cond){
|
inline bool is_jump_to_self_enabled(finish_cond_e cond){
|
||||||
@@ -290,7 +242,7 @@ inline bool is_jump_to_self_enabled(finish_cond_e cond){
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t icount_limit){
|
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e cond, virt_addr_t start, uint64_t count_limit){
|
||||||
auto pc=start;
|
auto pc=start;
|
||||||
auto* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
|
auto* PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC]);
|
||||||
auto* NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
|
auto* NEXT_PC = reinterpret_cast<uint${addrDataWidth}_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::NEXT_PC]);
|
||||||
@@ -303,23 +255,35 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||||||
auto *const data = reinterpret_cast<uint8_t*>(&instr);
|
auto *const data = reinterpret_cast<uint8_t*>(&instr);
|
||||||
|
|
||||||
while(!this->core.should_stop() &&
|
while(!this->core.should_stop() &&
|
||||||
!(is_count_limit_enabled(cond) && icount >= icount_limit)){
|
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
||||||
|
!(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){
|
||||||
|
if(this->debugging_enabled())
|
||||||
|
this->tgt_adapter->check_continue(*PC);
|
||||||
|
pc.val=*PC;
|
||||||
if(fetch_ins(pc, data)!=iss::Ok){
|
if(fetch_ins(pc, data)!=iss::Ok){
|
||||||
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
||||||
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
|
process_spawn_blocks();
|
||||||
|
if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
||||||
|
pc.val = super::core.enter_trap(arch::traits<ARCH>::RV_CAUSE_FETCH_ACCESS<<16, pc.val, 0);
|
||||||
} else {
|
} else {
|
||||||
if (is_jump_to_self_enabled(cond) &&
|
if (is_jump_to_self_enabled(cond) &&
|
||||||
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||||
auto inst_id = decode_instr(root, instr);
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
||||||
|
opcode_e inst_id = arch::traits<ARCH>::opcode_e::MAX_OPCODE;;
|
||||||
|
if(inst_index <instr_descr.size())
|
||||||
|
inst_id = instr_descr[inst_index].op;
|
||||||
|
|
||||||
// pre execution stuff
|
// pre execution stuff
|
||||||
this->core.reg.last_branch = 0;
|
this->core.reg.last_branch = 0;
|
||||||
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, static_cast<unsigned>(inst_id));
|
||||||
|
try{
|
||||||
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
switch(inst_id){<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
case arch::traits<ARCH>::opcode_e::${instr.name}: {
|
case arch::traits<ARCH>::opcode_e::${instr.name}: {
|
||||||
<%instr.fields.eachLine{%>${it}
|
<%instr.fields.eachLine{%>${it}
|
||||||
<%}%>if(this->disass_enabled){
|
<%}%>if(this->disass_enabled){
|
||||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
|
this->core.disass_output(pc.val, mnemonic);
|
||||||
}
|
}
|
||||||
// used registers<%instr.usedVariables.each{ k,v->
|
// used registers<%instr.usedVariables.each{ k,v->
|
||||||
if(v.isArray) {%>
|
if(v.isArray) {%>
|
||||||
@@ -329,13 +293,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||||||
*NEXT_PC = *PC + ${instr.length/8};
|
*NEXT_PC = *PC + ${instr.length/8};
|
||||||
// execute instruction<%instr.behavior.eachLine{%>
|
// execute instruction<%instr.behavior.eachLine{%>
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
TRAP_${instr.name}:break;
|
break;
|
||||||
}// @suppress("No break at end of case")<%}%>
|
}// @suppress("No break at end of case")<%}%>
|
||||||
default: {
|
default: {
|
||||||
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
*NEXT_PC = *PC + ((instr & 3) == 3 ? 4 : 2);
|
||||||
raise(0, 2);
|
raise(0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}catch(memory_access_exception& e){}
|
||||||
// post execution stuff
|
// post execution stuff
|
||||||
process_spawn_blocks();
|
process_spawn_blocks();
|
||||||
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
|
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, static_cast<unsigned>(inst_id));
|
||||||
@@ -343,16 +308,18 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
|
|||||||
// this->core.reg.trap_state = this->core.reg.pending_trap;
|
// this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||||
// trap check
|
// trap check
|
||||||
if(trap_state!=0){
|
if(trap_state!=0){
|
||||||
super::core.enter_trap(trap_state, pc.val, instr);
|
//In case of Instruction address misaligned (cause = 0 and trapid = 0) need the targeted addr (in tval)
|
||||||
|
auto mcause = (trap_state>>16) & 0xff;
|
||||||
|
super::core.enter_trap(trap_state, pc.val, mcause ? instr:tval);
|
||||||
} else {
|
} else {
|
||||||
icount++;
|
icount++;
|
||||||
instret++;
|
instret++;
|
||||||
}
|
}
|
||||||
cycle++;
|
*PC = *NEXT_PC;
|
||||||
pc.val=*NEXT_PC;
|
|
||||||
this->core.reg.PC = this->core.reg.NEXT_PC;
|
|
||||||
this->core.reg.trap_state = this->core.reg.pending_trap;
|
this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||||
}
|
}
|
||||||
|
fetch_count++;
|
||||||
|
cycle++;
|
||||||
}
|
}
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
@@ -368,24 +335,33 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
|
|||||||
} // namespace interp
|
} // namespace interp
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
||||||
#include <iss/factory.h>
|
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
#include <iss/arch/riscv_hart_mu_p.h>
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
|
#include <iss/factory.h>
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|interp", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|interp", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new interp::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
* Copyright (C) 2017-2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -29,14 +29,17 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
#include <iss/iss.h>
|
#include <iss/iss.h>
|
||||||
#include <iss/llvm/vm_base.h>
|
#include <iss/llvm/vm_base.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
|
#include <iss/instruction_decoder.h>
|
||||||
|
<%def fcsr = registers.find {it.name=='FCSR'}
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
#include <vm/fp_functions.h><%}%>
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
@@ -58,6 +61,7 @@ using namespace iss::debugger;
|
|||||||
|
|
||||||
template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> {
|
template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> {
|
||||||
public:
|
public:
|
||||||
|
using traits = arch::traits<ARCH>;
|
||||||
using super = typename iss::llvm::vm_base<ARCH>;
|
using super = typename iss::llvm::vm_base<ARCH>;
|
||||||
using virt_addr_t = typename super::virt_addr_t;
|
using virt_addr_t = typename super::virt_addr_t;
|
||||||
using phys_addr_t = typename super::phys_addr_t;
|
using phys_addr_t = typename super::phys_addr_t;
|
||||||
@@ -80,15 +84,17 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
using vm_base<ARCH>::get_reg_ptr;
|
using vm_base<ARCH>::get_reg_ptr;
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
<%if(fcsr != null) {%>
|
||||||
|
inline const char *fname(size_t index){return index < 32?name(index+traits::F0):"illegal";}
|
||||||
|
<%}%>
|
||||||
template <typename T> inline ConstantInt *size(T type) {
|
template <typename T> inline ConstantInt *size(T type) {
|
||||||
return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
|
return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_module(Module* m) override {
|
void setup_module(Module* m) override {
|
||||||
super::setup_module(m);
|
super::setup_module(m);
|
||||||
iss::llvm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE, traits<ARCH>::XLEN);
|
iss::llvm::fp_impl::add_fp_functions_2_module(m, traits::FP_REGS_SIZE, traits::XLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) {
|
inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) {
|
||||||
@@ -98,219 +104,242 @@ protected:
|
|||||||
std::tuple<continuation_e, BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override;
|
std::tuple<continuation_e, BasicBlock *> gen_single_inst_behavior(virt_addr_t &, unsigned int &, BasicBlock *) override;
|
||||||
|
|
||||||
void gen_leave_behavior(BasicBlock *leave_blk) override;
|
void gen_leave_behavior(BasicBlock *leave_blk) override;
|
||||||
|
|
||||||
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
|
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
|
||||||
|
|
||||||
void gen_leave_trap(unsigned lvl);
|
void gen_leave_trap(unsigned lvl);
|
||||||
|
|
||||||
void gen_wait(unsigned type);
|
void gen_wait(unsigned type);
|
||||||
|
void set_tval(uint64_t new_tval);
|
||||||
|
void set_tval(Value* new_tval);
|
||||||
void gen_trap_behavior(BasicBlock *) override;
|
void gen_trap_behavior(BasicBlock *) override;
|
||||||
|
void gen_instr_prologue();
|
||||||
void gen_trap_check(BasicBlock *bb);
|
void gen_instr_epilogue(BasicBlock *bb);
|
||||||
|
|
||||||
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||||
return this->builder.CreateLoad(this->get_typeptr(i), get_reg_ptr(i), false);
|
return this->builder.CreateLoad(this->get_typeptr(i), get_reg_ptr(i), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
inline void gen_set_pc(virt_addr_t pc, unsigned reg_num) {
|
||||||
Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits<ARCH>::XLEN, pc.val),
|
Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val),
|
||||||
this->get_type(traits<ARCH>::XLEN));
|
this->get_type(traits::XLEN));
|
||||||
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// some compile time constants
|
// some compile time constants
|
||||||
// enum { MASK16 = 0b1111110001100011, MASK32 = 0b11111111111100000111000001111111 };
|
|
||||||
enum { MASK16 = 0b1111111111111111, MASK32 = 0b11111111111100000111000001111111 };
|
|
||||||
enum { EXTR_MASK16 = MASK16 >> 2, EXTR_MASK32 = MASK32 >> 2 };
|
|
||||||
enum { LUT_SIZE = 1 << util::bit_count(static_cast<uint64_t>(EXTR_MASK32)), LUT_SIZE_C = 1 << util::bit_count(static_cast<uint64_t>(EXTR_MASK16)) };
|
|
||||||
|
|
||||||
using this_class = vm_impl<ARCH>;
|
using this_class = vm_impl<ARCH>;
|
||||||
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
|
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
|
||||||
code_word_t instr,
|
code_word_t instr,
|
||||||
BasicBlock *bb);
|
BasicBlock *bb);
|
||||||
std::array<compile_func, LUT_SIZE> lut;
|
template<unsigned W, typename U, typename S = typename std::make_signed<U>::type>
|
||||||
|
inline S sext(U from) {
|
||||||
std::array<compile_func, LUT_SIZE_C> lut_00, lut_01, lut_10;
|
auto mask = (1ULL<<W) - 1;
|
||||||
std::array<compile_func, LUT_SIZE> lut_11;
|
auto sign_mask = 1ULL<<(W-1);
|
||||||
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
std::array<compile_func *, 4> qlut;
|
|
||||||
|
|
||||||
std::array<const uint32_t, 4> lutmasks = {{EXTR_MASK16, EXTR_MASK16, EXTR_MASK16, EXTR_MASK32}};
|
|
||||||
|
|
||||||
void expand_bit_mask(int pos, uint32_t mask, uint32_t value, uint32_t valid, uint32_t idx, compile_func lut[],
|
|
||||||
compile_func f) {
|
|
||||||
if (pos < 0) {
|
|
||||||
lut[idx] = f;
|
|
||||||
} else {
|
|
||||||
auto bitmask = 1UL << pos;
|
|
||||||
if ((mask & bitmask) == 0) {
|
|
||||||
expand_bit_mask(pos - 1, mask, value, valid, idx, lut, f);
|
|
||||||
} else {
|
|
||||||
if ((valid & bitmask) == 0) {
|
|
||||||
expand_bit_mask(pos - 1, mask, value, valid, (idx << 1), lut, f);
|
|
||||||
expand_bit_mask(pos - 1, mask, value, valid, (idx << 1) + 1, lut, f);
|
|
||||||
} else {
|
|
||||||
auto new_val = idx << 1;
|
|
||||||
if ((value & bitmask) != 0) new_val++;
|
|
||||||
expand_bit_mask(pos - 1, mask, value, valid, new_val, lut, f);
|
|
||||||
}
|
}
|
||||||
}
|
<%functions.each{ it.eachLine { %>
|
||||||
}
|
${it}<%}%>
|
||||||
}
|
<%}%>
|
||||||
|
|
||||||
inline uint32_t extract_fields(uint32_t val) { return extract_fields(29, val >> 2, lutmasks[val & 0x3], 0); }
|
|
||||||
|
|
||||||
uint32_t extract_fields(int pos, uint32_t val, uint32_t mask, uint32_t lut_val) {
|
|
||||||
if (pos >= 0) {
|
|
||||||
auto bitmask = 1UL << pos;
|
|
||||||
if ((mask & bitmask) == 0) {
|
|
||||||
lut_val = extract_fields(pos - 1, val, mask, lut_val);
|
|
||||||
} else {
|
|
||||||
auto new_val = lut_val << 1;
|
|
||||||
if ((val & bitmask) != 0) new_val++;
|
|
||||||
lut_val = extract_fields(pos - 1, val, mask, new_val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return lut_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* start opcode definitions
|
* start opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct InstructionDesriptor {
|
struct instruction_descriptor {
|
||||||
size_t length;
|
uint32_t length;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
compile_func op;
|
compile_func op;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
const std::array<instruction_descriptor, ${instructions.size()}> instr_descr = {{
|
||||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
/* instruction ${instr.instruction.name} */
|
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
||||||
{${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
{${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
//needs to be declared after instr_descr
|
||||||
|
decoder instr_decoder;
|
||||||
|
|
||||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
/* instruction ${idx}: ${instr.name} */
|
/* instruction ${idx}: ${instr.name} */
|
||||||
std::tuple<continuation_e, BasicBlock*> __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){<%instr.code.eachLine{%>
|
std::tuple<continuation_e, BasicBlock*> __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, BasicBlock* bb){
|
||||||
|
uint64_t PC = pc.val;
|
||||||
|
<%instr.fields.eachLine{%>${it}
|
||||||
|
<%}%>if(this->disass_enabled){
|
||||||
|
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
|
std::vector<Value*> args {
|
||||||
|
this->core_ptr,
|
||||||
|
this->gen_const(64, pc.val),
|
||||||
|
this->builder.CreateGlobalStringPtr(mnemonic),
|
||||||
|
};
|
||||||
|
this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
|
||||||
|
}
|
||||||
|
bb->setName(fmt::format("${instr.name}_0x{:X}",pc.val));
|
||||||
|
this->gen_sync(PRE_SYNC,${idx});
|
||||||
|
|
||||||
|
this->gen_set_pc(pc, traits::PC);
|
||||||
|
this->set_tval(instr);
|
||||||
|
pc=pc+ ${instr.length/8};
|
||||||
|
this->gen_set_pc(pc, traits::NEXT_PC);
|
||||||
|
|
||||||
|
this->gen_instr_prologue();
|
||||||
|
/*generate behavior*/
|
||||||
|
<%instr.behavior.eachLine{%>${it}
|
||||||
|
<%}%>
|
||||||
|
this->gen_sync(POST_SYNC, ${idx});
|
||||||
|
this->gen_instr_epilogue(bb);
|
||||||
|
this->builder.CreateBr(bb);
|
||||||
|
return returnValue;
|
||||||
}
|
}
|
||||||
<%}%>
|
<%}%>
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* end opcode definitions
|
* end opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
std::tuple<continuation_e, BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, BasicBlock *bb) {
|
std::tuple<continuation_e, BasicBlock *> illegal_instruction(virt_addr_t &pc, code_word_t instr, BasicBlock *bb) {
|
||||||
|
if(this->disass_enabled){
|
||||||
|
auto mnemonic = std::string("illegal_instruction");
|
||||||
|
std::vector<Value*> args {
|
||||||
|
this->core_ptr,
|
||||||
|
this->gen_const(64, pc.val),
|
||||||
|
this->builder.CreateGlobalStringPtr(mnemonic),
|
||||||
|
};
|
||||||
|
this->builder.CreateCall(this->mod->getFunction("print_disass"), args);
|
||||||
|
}
|
||||||
this->gen_sync(iss::PRE_SYNC, instr_descr.size());
|
this->gen_sync(iss::PRE_SYNC, instr_descr.size());
|
||||||
this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), true),
|
this->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), true),
|
||||||
get_reg_ptr(traits<ARCH>::PC), true);
|
get_reg_ptr(traits::PC), true);
|
||||||
this->builder.CreateStore(
|
this->builder.CreateStore(
|
||||||
this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits<ARCH>::ICOUNT), get_reg_ptr(traits<ARCH>::ICOUNT), true),
|
this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits::ICOUNT), get_reg_ptr(traits::ICOUNT), true),
|
||||||
this->gen_const(64U, 1)),
|
this->gen_const(64U, 1)),
|
||||||
get_reg_ptr(traits<ARCH>::ICOUNT), true);
|
get_reg_ptr(traits::ICOUNT), true);
|
||||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
|
this->set_tval(instr);
|
||||||
this->gen_raise_trap(0, 2); // illegal instruction trap
|
this->gen_raise_trap(0, 2); // illegal instruction trap
|
||||||
this->gen_sync(iss::POST_SYNC, instr_descr.size());
|
this->gen_sync(iss::POST_SYNC, instr_descr.size());
|
||||||
this->gen_trap_check(this->leave_blk);
|
bb = this->leave_blk;
|
||||||
return std::make_tuple(BRANCH, nullptr);
|
this->gen_instr_epilogue(bb);
|
||||||
|
this->builder.CreateBr(bb);
|
||||||
|
return std::make_tuple(ILLEGAL_INSTR, nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
|
||||||
volatile CODE_WORD x = insn;
|
volatile CODE_WORD x = instr;
|
||||||
insn = 2 * x;
|
instr = 2 * x;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
: vm_base<ARCH>(core, core_id, cluster_id) {
|
: vm_base<ARCH>(core, core_id, cluster_id)
|
||||||
qlut[0] = lut_00.data();
|
, instr_decoder([this]() {
|
||||||
qlut[1] = lut_01.data();
|
std::vector<generic_instruction_descriptor> g_instr_descr;
|
||||||
qlut[2] = lut_10.data();
|
g_instr_descr.reserve(instr_descr.size());
|
||||||
qlut[3] = lut_11.data();
|
for (uint32_t i = 0; i < instr_descr.size(); ++i) {
|
||||||
for (auto instr : instr_descr) {
|
generic_instruction_descriptor new_instr_descr {instr_descr[i].value, instr_descr[i].mask, i};
|
||||||
auto quantrant = instr.value & 0x3;
|
g_instr_descr.push_back(new_instr_descr);
|
||||||
expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return std::move(g_instr_descr);
|
||||||
|
}()) {}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
std::tuple<continuation_e, BasicBlock *>
|
std::tuple<continuation_e, BasicBlock *>
|
||||||
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) {
|
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, BasicBlock *this_block) {
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t insn = 0;
|
code_word_t instr = 0;
|
||||||
// const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
// const typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||||
phys_addr_t paddr(pc);
|
phys_addr_t paddr(pc);
|
||||||
auto *const data = (uint8_t *)&insn;
|
auto *const data = (uint8_t *)&instr;
|
||||||
paddr = this->core.v2p(pc);
|
if(this->core.has_mmu())
|
||||||
//TODO: re-add page handling
|
paddr = this->core.virt2phys(pc);
|
||||||
// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
|
||||||
// auto res = this->core.read(paddr, 2, data);
|
|
||||||
// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
|
||||||
// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction
|
|
||||||
// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
auto res = this->core.read(paddr, 4, data);
|
auto res = this->core.read(paddr, 4, data);
|
||||||
if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
if (res != iss::Ok)
|
||||||
// }
|
return std::make_tuple(ILLEGAL_FETCH, nullptr);
|
||||||
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
if (instr == 0x0000006f || (instr&0xffff)==0xa001)
|
||||||
// curr pc on stack
|
return std::make_tuple(JUMP_TO_SELF, nullptr);
|
||||||
++inst_cnt;
|
++inst_cnt;
|
||||||
auto lut_val = extract_fields(insn);
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
||||||
auto f = qlut[insn & 0x3][lut_val];
|
compile_func f = nullptr;
|
||||||
|
if(inst_index < instr_descr.size())
|
||||||
|
f = instr_descr[inst_index].op;
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
f = &this_class::illegal_intruction;
|
f = &this_class::illegal_instruction;
|
||||||
}
|
}
|
||||||
return (this->*f)(pc, insn, this_block);
|
return (this->*f)(pc, instr, this_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
|
||||||
this->builder.SetInsertPoint(leave_blk);
|
this->builder.SetInsertPoint(leave_blk);
|
||||||
this->builder.CreateRet(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false));
|
this->builder.CreateRet(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC),get_reg_ptr(traits::NEXT_PC), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_raise_trap(uint16_t trap_id, uint16_t cause) {
|
||||||
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true);
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
this->builder.CreateBr(this->trap_blk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_leave_trap(unsigned lvl) {
|
||||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
|
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
|
||||||
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
||||||
auto *PC_val = this->gen_read_mem(traits<ARCH>::CSR, (lvl << 8) + 0x41, traits<ARCH>::XLEN / 8);
|
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||||
this->builder.CreateStore(PC_val, get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()), get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(unsigned type) {
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) };
|
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) };
|
||||||
this->builder.CreateCall(this->mod->getFunction("wait"), args);
|
this->builder.CreateCall(this->mod->getFunction("wait"), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
template <typename ARCH>
|
||||||
|
inline void vm_impl<ARCH>::set_tval(uint64_t tval) {
|
||||||
|
auto tmp_tval = this->gen_const(64, tval);
|
||||||
|
this->set_tval(tmp_tval);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
inline void vm_impl<ARCH>::set_tval(Value* new_tval) {
|
||||||
|
this->builder.CreateStore(this->gen_ext(new_tval, 64, false), this->tval);
|
||||||
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
||||||
this->builder.SetInsertPoint(trap_blk);
|
this->builder.SetInsertPoint(trap_blk);
|
||||||
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
|
||||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
auto *cur_pc_val = this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), true);
|
||||||
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
std::vector<Value *> args{this->core_ptr,
|
||||||
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
this->adj_to64(trap_state_val),
|
||||||
this->adj_to64(this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::PC), get_reg_ptr(traits<ARCH>::PC), false))};
|
this->adj_to64(cur_pc_val),
|
||||||
|
this->adj_to64(this->builder.CreateLoad(this->get_type(64),this->tval))};
|
||||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||||
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::NEXT_PC), get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||||
|
|
||||||
|
auto *trap_addr_val = this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), false);
|
||||||
this->builder.CreateRet(trap_addr_val);
|
this->builder.CreateRet(trap_addr_val);
|
||||||
}
|
}
|
||||||
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_instr_prologue() {
|
||||||
|
auto* trap_val =
|
||||||
|
this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::PENDING_TRAP), get_reg_ptr(arch::traits<ARCH>::PENDING_TRAP));
|
||||||
|
this->builder.CreateStore(trap_val, get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), false);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
|
|
||||||
auto *v = this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::TRAP_STATE), get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true);
|
template <typename ARCH>
|
||||||
|
void vm_impl<ARCH>::gen_instr_epilogue(BasicBlock *bb) {
|
||||||
|
auto* target_bb = BasicBlock::Create(this->mod->getContext(), "", this->func, bb);
|
||||||
|
auto *v = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
|
||||||
this->gen_cond_branch(this->builder.CreateICmp(
|
this->gen_cond_branch(this->builder.CreateICmp(
|
||||||
ICmpInst::ICMP_EQ, v,
|
ICmpInst::ICMP_EQ, v,
|
||||||
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
|
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
|
||||||
bb, this->trap_blk, 1);
|
target_bb, this->trap_blk, 1);
|
||||||
|
this->builder.SetInsertPoint(target_bb);
|
||||||
|
// update icount
|
||||||
|
auto* icount_val = this->builder.CreateAdd(
|
||||||
|
this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::ICOUNT), get_reg_ptr(arch::traits<ARCH>::ICOUNT)), this->gen_const(64U, 1));
|
||||||
|
this->builder.CreateStore(icount_val, get_reg_ptr(arch::traits<ARCH>::ICOUNT), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ${coreDef.name.toLowerCase()}
|
} // namespace ${coreDef.name.toLowerCase()}
|
||||||
@@ -324,24 +353,33 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
|
|||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
||||||
#include <iss/factory.h>
|
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
#include <iss/arch/riscv_hart_mu_p.h>
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
|
#include <iss/factory.h>
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|llvm", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|llvm", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto* vm = new llvm::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new llvm::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<std::function<void(arch_if*, arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t*, arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t*)>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|llvm", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|llvm", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto* vm = new llvm::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new llvm::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<std::function<void(arch_if*, arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t*, arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t*)>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2020 MINRES Technologies GmbH
|
* Copyright (C) 2020-2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
// clang-format off
|
||||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||||
#include <iss/debugger/gdb_session.h>
|
#include <iss/debugger/gdb_session.h>
|
||||||
#include <iss/debugger/server.h>
|
#include <iss/debugger/server.h>
|
||||||
@@ -37,7 +37,10 @@
|
|||||||
#include <iss/tcc/vm_base.h>
|
#include <iss/tcc/vm_base.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iss/instruction_decoder.h>
|
||||||
|
<%def fcsr = registers.find {it.name=='FCSR'}
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
#include <vm/fp_functions.h><%}%>
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
@@ -80,16 +83,21 @@ protected:
|
|||||||
using vm_base<ARCH>::get_reg_ptr;
|
using vm_base<ARCH>::get_reg_ptr;
|
||||||
|
|
||||||
using this_class = vm_impl<ARCH>;
|
using this_class = vm_impl<ARCH>;
|
||||||
using compile_ret_t = std::tuple<continuation_e>;
|
using compile_ret_t = continuation_e;
|
||||||
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&);
|
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr, tu_builder&);
|
||||||
|
|
||||||
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
inline const char *name(size_t index){return traits::reg_aliases.at(index);}
|
||||||
|
<%
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
inline const char *fname(size_t index){return index < 32?name(index+traits::F0):"illegal";}
|
||||||
|
<%}%>
|
||||||
|
void add_prologue(tu_builder& tu) override;
|
||||||
|
|
||||||
void setup_module(std::string m) override {
|
void setup_module(std::string m) override {
|
||||||
super::setup_module(m);
|
super::setup_module(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_ret_t gen_single_inst_behavior(virt_addr_t &, unsigned int &, tu_builder&) override;
|
compile_ret_t gen_single_inst_behavior(virt_addr_t &, tu_builder&) override;
|
||||||
|
|
||||||
void gen_trap_behavior(tu_builder& tu) override;
|
void gen_trap_behavior(tu_builder& tu) override;
|
||||||
|
|
||||||
@@ -97,7 +105,9 @@ protected:
|
|||||||
|
|
||||||
void gen_leave_trap(tu_builder& tu, unsigned lvl);
|
void gen_leave_trap(tu_builder& tu, unsigned lvl);
|
||||||
|
|
||||||
void gen_wait(tu_builder& tu, unsigned type);
|
inline void gen_set_tval(tu_builder& tu, uint64_t new_tval);
|
||||||
|
|
||||||
|
inline void gen_set_tval(tu_builder& tu, value new_tval);
|
||||||
|
|
||||||
inline void gen_trap_check(tu_builder& tu) {
|
inline void gen_trap_check(tu_builder& tu) {
|
||||||
tu("if(*trap_state!=0) goto trap_entry;");
|
tu("if(*trap_state!=0) goto trap_entry;");
|
||||||
@@ -128,47 +138,48 @@ protected:
|
|||||||
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
return (from & mask) | ((from & sign_mask) ? ~mask : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<%functions.each{ it.eachLine { %>
|
||||||
|
${it}<%}%>
|
||||||
|
<%}%>
|
||||||
private:
|
private:
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* start opcode definitions
|
* start opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
struct instruction_descriptor {
|
struct instruction_descriptor {
|
||||||
size_t length;
|
uint32_t length;
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
compile_func op;
|
compile_func op;
|
||||||
};
|
};
|
||||||
struct decoding_tree_node{
|
|
||||||
std::vector<instruction_descriptor> instrs;
|
|
||||||
std::vector<decoding_tree_node*> children;
|
|
||||||
uint32_t submask = std::numeric_limits<uint32_t>::max();
|
|
||||||
uint32_t value;
|
|
||||||
decoding_tree_node(uint32_t value) : value(value){}
|
|
||||||
};
|
|
||||||
|
|
||||||
decoding_tree_node* root {nullptr};
|
const std::array<instruction_descriptor, ${instructions.size()}> instr_descr = {{
|
||||||
|
|
||||||
const std::array<instruction_descriptor, ${instructions.size}> instr_descr = {{
|
|
||||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||||
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
/* instruction ${instr.instruction.name}, encoding '${instr.encoding}' */
|
||||||
{${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
{${instr.length}, ${instr.encoding}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
//needs to be declared after instr_descr
|
||||||
|
decoder instr_decoder;
|
||||||
|
|
||||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||||
/* instruction ${idx}: ${instr.name} */
|
/* instruction ${idx}: ${instr.name} */
|
||||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){
|
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){
|
||||||
tu("${instr.name}_{:#010x}:", pc.val);
|
tu("${instr.name}_{:#010x}:", pc.val);
|
||||||
vm_base<ARCH>::gen_sync(tu, PRE_SYNC,${idx});
|
vm_base<ARCH>::gen_sync(tu, PRE_SYNC,${idx});
|
||||||
|
uint64_t PC = pc.val;
|
||||||
<%instr.fields.eachLine{%>${it}
|
<%instr.fields.eachLine{%>${it}
|
||||||
<%}%>if(this->disass_enabled){
|
<%}%>if(this->disass_enabled){
|
||||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||||
${it}<%}%>
|
${it}<%}%>
|
||||||
|
tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic);
|
||||||
}
|
}
|
||||||
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
|
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
|
||||||
pc=pc+ ${instr.length/8};
|
pc=pc+ ${instr.length/8};
|
||||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||||
tu.open_scope();<%instr.behavior.eachLine{%>
|
tu.open_scope();
|
||||||
${it}<%}%>
|
this->gen_set_tval(tu, instr);
|
||||||
|
<%instr.behavior.eachLine{%>${it}
|
||||||
|
<%}%>
|
||||||
tu.close_scope();
|
tu.close_scope();
|
||||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
|
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
|
||||||
gen_trap_check(tu);
|
gen_trap_check(tu);
|
||||||
@@ -178,66 +189,18 @@ private:
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* end opcode definitions
|
* end opcode definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr, tu_builder& tu) {
|
compile_ret_t illegal_instruction(virt_addr_t &pc, code_word_t instr, tu_builder& tu) {
|
||||||
vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size());
|
vm_impl::gen_sync(tu, iss::PRE_SYNC, instr_descr.size());
|
||||||
|
if(this->disass_enabled){
|
||||||
|
/* generate console output when executing the command */
|
||||||
|
tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, std::string("illegal_instruction"));
|
||||||
|
}
|
||||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||||
gen_raise_trap(tu, 0, 2); // illegal instruction trap
|
gen_raise_trap(tu, 0, static_cast<int32_t>(traits:: RV_CAUSE_ILLEGAL_INSTRUCTION));
|
||||||
|
this->gen_set_tval(tu, instr);
|
||||||
vm_impl::gen_sync(tu, iss::POST_SYNC, instr_descr.size());
|
vm_impl::gen_sync(tu, iss::POST_SYNC, instr_descr.size());
|
||||||
vm_impl::gen_trap_check(tu);
|
vm_impl::gen_trap_check(tu);
|
||||||
return BRANCH;
|
return ILLEGAL_INSTR;
|
||||||
}
|
|
||||||
|
|
||||||
//decoding functionality
|
|
||||||
|
|
||||||
void populate_decoding_tree(decoding_tree_node* root){
|
|
||||||
//create submask
|
|
||||||
for(auto instr: root->instrs){
|
|
||||||
root->submask &= instr.mask;
|
|
||||||
}
|
|
||||||
//put each instr according to submask&encoding into children
|
|
||||||
for(auto instr: root->instrs){
|
|
||||||
bool foundMatch = false;
|
|
||||||
for(auto child: root->children){
|
|
||||||
//use value as identifying trait
|
|
||||||
if(child->value == (instr.value&root->submask)){
|
|
||||||
child->instrs.push_back(instr);
|
|
||||||
foundMatch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!foundMatch){
|
|
||||||
decoding_tree_node* child = new decoding_tree_node(instr.value&root->submask);
|
|
||||||
child->instrs.push_back(instr);
|
|
||||||
root->children.push_back(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
root->instrs.clear();
|
|
||||||
//call populate_decoding_tree for all children
|
|
||||||
if(root->children.size() >1)
|
|
||||||
for(auto child: root->children){
|
|
||||||
populate_decoding_tree(child);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
//sort instrs by value of the mask, this works bc we want to have the least restrictive one last
|
|
||||||
std::sort(root->children[0]->instrs.begin(), root->children[0]->instrs.end(), [](const instruction_descriptor& instr1, const instruction_descriptor& instr2) {
|
|
||||||
return instr1.mask > instr2.mask;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compile_func decode_instr(decoding_tree_node* node, code_word_t word){
|
|
||||||
if(!node->children.size()){
|
|
||||||
if(node->instrs.size() == 1) return node->instrs[0].op;
|
|
||||||
for(auto instr : node->instrs){
|
|
||||||
if((instr.mask&word) == instr.value) return instr.op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for(auto child : node->children){
|
|
||||||
if (child->value == (node->submask&word)){
|
|
||||||
return decode_instr(child, word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -250,64 +213,102 @@ template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
|
|||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
|
||||||
: vm_base<ARCH>(core, core_id, cluster_id) {
|
: vm_base<ARCH>(core, core_id, cluster_id)
|
||||||
root = new decoding_tree_node(std::numeric_limits<uint32_t>::max());
|
, instr_decoder([this]() {
|
||||||
for(auto instr:instr_descr){
|
std::vector<generic_instruction_descriptor> g_instr_descr;
|
||||||
root->instrs.push_back(instr);
|
g_instr_descr.reserve(instr_descr.size());
|
||||||
}
|
for (uint32_t i = 0; i < instr_descr.size(); ++i) {
|
||||||
populate_decoding_tree(root);
|
generic_instruction_descriptor new_instr_descr {instr_descr[i].value, instr_descr[i].mask, i};
|
||||||
|
g_instr_descr.push_back(new_instr_descr);
|
||||||
}
|
}
|
||||||
|
return std::move(g_instr_descr);
|
||||||
|
}()) {}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
std::tuple<continuation_e>
|
continuation_e
|
||||||
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, unsigned int &inst_cnt, tu_builder& tu) {
|
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, tu_builder& tu) {
|
||||||
// we fetch at max 4 byte, alignment is 2
|
// we fetch at max 4 byte, alignment is 2
|
||||||
enum {TRAP_ID=1<<16};
|
enum {TRAP_ID=1<<16};
|
||||||
code_word_t instr = 0;
|
code_word_t instr = 0;
|
||||||
phys_addr_t paddr(pc);
|
phys_addr_t paddr(pc);
|
||||||
if(this->core.has_mmu())
|
if(this->core.has_mmu())
|
||||||
paddr = this->core.virt2phys(pc);
|
paddr = this->core.virt2phys(pc);
|
||||||
//TODO: re-add page handling
|
|
||||||
// if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
|
||||||
// auto res = this->core.read(paddr, 2, data);
|
|
||||||
// if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
|
||||||
// if ((insn & 0x3) == 0x3) { // this is a 32bit instruction
|
|
||||||
// res = this->core.read(this->core.v2p(pc + 2), 2, data + 2);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
auto res = this->core.read(paddr, 4, reinterpret_cast<uint8_t*>(&instr));
|
auto res = this->core.read(paddr, 4, reinterpret_cast<uint8_t*>(&instr));
|
||||||
if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
if (res != iss::Ok)
|
||||||
// }
|
return ILLEGAL_FETCH;
|
||||||
if (instr == 0x0000006f || (instr&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
if (instr == 0x0000006f || (instr&0xffff)==0xa001)
|
||||||
// curr pc on stack
|
return JUMP_TO_SELF;
|
||||||
++inst_cnt;
|
uint32_t inst_index = instr_decoder.decode_instr(instr);
|
||||||
auto f = decode_instr(root, instr);
|
compile_func f = nullptr;
|
||||||
|
if(inst_index < instr_descr.size())
|
||||||
|
f = instr_descr[inst_index].op;
|
||||||
if (f == nullptr) {
|
if (f == nullptr) {
|
||||||
f = &this_class::illegal_intruction;
|
f = &this_class::illegal_instruction;
|
||||||
}
|
}
|
||||||
return (this->*f)(pc, instr, tu);
|
return (this->*f)(pc, instr, tu);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause) {
|
||||||
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
tu(" *trap_state = {:#x};", 0x80 << 24 | (cause << 16) | trap_id);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||||
tu("leave_trap(core_ptr, {});", lvl);
|
tu("leave_trap(core_ptr, {});", lvl);
|
||||||
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
tu.store(traits::NEXT_PC, tu.read_mem(traits::CSR, (lvl << 8) + 0x41, traits::XLEN));
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(), 32));
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP), 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_wait(tu_builder& tu, unsigned type) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_set_tval(tu_builder& tu, uint64_t new_tval) {
|
||||||
|
tu(fmt::format("tval = {};", new_tval));
|
||||||
|
}
|
||||||
|
template <typename ARCH> void vm_impl<ARCH>::gen_set_tval(tu_builder& tu, value new_tval) {
|
||||||
|
tu(fmt::format("tval = {};", new_tval.str));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(tu_builder& tu) {
|
||||||
tu("trap_entry:");
|
tu("trap_entry:");
|
||||||
tu("enter_trap(core_ptr, *trap_state, *pc, 0);");
|
this->gen_sync(tu, POST_SYNC, -1);
|
||||||
tu.store(traits::LAST_BRANCH, tu.constant(std::numeric_limits<uint32_t>::max(),32));
|
tu("enter_trap(core_ptr, *trap_state, *pc, tval);");
|
||||||
|
tu.store(traits::LAST_BRANCH, tu.constant(static_cast<int>(UNKNOWN_JUMP),32));
|
||||||
tu("return *next_pc;");
|
tu("return *next_pc;");
|
||||||
}
|
}
|
||||||
|
<%
|
||||||
|
|
||||||
|
template <typename ARCH> void vm_impl<ARCH>::add_prologue(tu_builder& tu){
|
||||||
|
std::ostringstream os;
|
||||||
|
os << add_reg_ptr("trap_state", arch::traits<ARCH>::TRAP_STATE);
|
||||||
|
os << add_reg_ptr("pending_trap", arch::traits<ARCH>::PENDING_TRAP);
|
||||||
|
if(fcsr != null) {%>
|
||||||
|
os << "uint32_t (*fget_flags)()=" << (uintptr_t)&fget_flags << ";\\n";
|
||||||
|
os << "uint32_t (*fadd_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fadd_s << ";\\n";
|
||||||
|
os << "uint32_t (*fsub_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fsub_s << ";\\n";
|
||||||
|
os << "uint32_t (*fmul_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fmul_s << ";\\n";
|
||||||
|
os << "uint32_t (*fdiv_s)(uint32_t v1, uint32_t v2, uint8_t mode)=" << (uintptr_t)&fdiv_s << ";\\n";
|
||||||
|
os << "uint32_t (*fsqrt_s)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&fsqrt_s << ";\\n";
|
||||||
|
os << "uint32_t (*fcmp_s)(uint32_t v1, uint32_t v2, uint32_t op)=" << (uintptr_t)&fcmp_s << ";\\n";
|
||||||
|
os << "uint32_t (*fcvt_s)(uint32_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_s << ";\\n";
|
||||||
|
os << "uint32_t (*fmadd_s)(uint32_t v1, uint32_t v2, uint32_t v3, uint32_t op, uint8_t mode)=" << (uintptr_t)&fmadd_s << ";\\n";
|
||||||
|
os << "uint32_t (*fsel_s)(uint32_t v1, uint32_t v2, uint32_t op)=" << (uintptr_t)&fsel_s << ";\\n";
|
||||||
|
os << "uint32_t (*fclass_s)( uint32_t v1 )=" << (uintptr_t)&fclass_s << ";\\n";
|
||||||
|
os << "uint32_t (*fconv_d2f)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&fconv_d2f << ";\\n";
|
||||||
|
os << "uint64_t (*fconv_f2d)(uint32_t v1, uint8_t mode)=" << (uintptr_t)&fconv_f2d << ";\\n";
|
||||||
|
os << "uint64_t (*fadd_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fadd_d << ";\\n";
|
||||||
|
os << "uint64_t (*fsub_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fsub_d << ";\\n";
|
||||||
|
os << "uint64_t (*fmul_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fmul_d << ";\\n";
|
||||||
|
os << "uint64_t (*fdiv_d)(uint64_t v1, uint64_t v2, uint8_t mode)=" << (uintptr_t)&fdiv_d << ";\\n";
|
||||||
|
os << "uint64_t (*fsqrt_d)(uint64_t v1, uint8_t mode)=" << (uintptr_t)&fsqrt_d << ";\\n";
|
||||||
|
os << "uint64_t (*fcmp_d)(uint64_t v1, uint64_t v2, uint32_t op)=" << (uintptr_t)&fcmp_d << ";\\n";
|
||||||
|
os << "uint64_t (*fcvt_d)(uint64_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_d << ";\\n";
|
||||||
|
os << "uint64_t (*fmadd_d)(uint64_t v1, uint64_t v2, uint64_t v3, uint32_t op, uint8_t mode)=" << (uintptr_t)&fmadd_d << ";\\n";
|
||||||
|
os << "uint64_t (*fsel_d)(uint64_t v1, uint64_t v2, uint32_t op)=" << (uintptr_t)&fsel_d << ";\\n";
|
||||||
|
os << "uint64_t (*fclass_d)(uint64_t v1 )=" << (uintptr_t)&fclass_d << ";\\n";
|
||||||
|
os << "uint64_t (*fcvt_32_64)(uint32_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_32_64 << ";\\n";
|
||||||
|
os << "uint32_t (*fcvt_64_32)(uint64_t v1, uint32_t op, uint8_t mode)=" << (uintptr_t)&fcvt_64_32 << ";\\n";
|
||||||
|
os << "uint32_t (*unbox_s)(uint64_t v)=" << (uintptr_t)&unbox_s << ";\\n";
|
||||||
|
<%}%>
|
||||||
|
tu.add_prologue(os.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace ${coreDef.name.toLowerCase()}
|
} // namespace ${coreDef.name.toLowerCase()}
|
||||||
|
|
||||||
@@ -320,24 +321,33 @@ std::unique_ptr<vm_if> create<arch::${coreDef.name.toLowerCase()}>(arch::${coreD
|
|||||||
} // namesapce tcc
|
} // namesapce tcc
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
||||||
#include <iss/factory.h>
|
|
||||||
#include <iss/arch/riscv_hart_m_p.h>
|
#include <iss/arch/riscv_hart_m_p.h>
|
||||||
#include <iss/arch/riscv_hart_mu_p.h>
|
#include <iss/arch/riscv_hart_mu_p.h>
|
||||||
|
#include <iss/factory.h>
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace {
|
namespace {
|
||||||
volatile std::array<bool, 2> dummy = {
|
volatile std::array<bool, 2> dummy = {
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|m_p|tcc", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_m_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
}),
|
}),
|
||||||
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void*) -> std::tuple<cpu_ptr, vm_ptr>{
|
core_factory::instance().register_creator("${coreDef.name.toLowerCase()}|mu_p|tcc", [](unsigned port, void* init_data) -> std::tuple<cpu_ptr, vm_ptr>{
|
||||||
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
auto* cpu = new iss::arch::riscv_hart_mu_p<iss::arch::${coreDef.name.toLowerCase()}>();
|
||||||
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
auto vm = new tcc::${coreDef.name.toLowerCase()}::vm_impl<arch::${coreDef.name.toLowerCase()}>(*cpu, false);
|
||||||
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
if (port != 0) debugger::server<debugger::gdb_session>::run_server(vm, port);
|
||||||
|
if(init_data){
|
||||||
|
auto* cb = reinterpret_cast<semihosting_cb_t<arch::traits<arch::${coreDef.name.toLowerCase()}>::reg_t>*>(init_data);
|
||||||
|
cpu->set_semihosting_callback(*cb);
|
||||||
|
}
|
||||||
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
return {cpu_ptr{cpu}, vm_ptr{vm}};
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build/*/*.o
|
||||||
|
build/*/*.a
|
||||||
@@ -327,7 +327,7 @@ set(OTHERS
|
|||||||
|
|
||||||
set(LIB_SOURCES ${PRIMITIVES} ${SPECIALIZE} ${OTHERS})
|
set(LIB_SOURCES ${PRIMITIVES} ${SPECIALIZE} ${OTHERS})
|
||||||
|
|
||||||
add_library(softfloat ${LIB_SOURCES})
|
add_library(softfloat STATIC ${LIB_SOURCES})
|
||||||
set_property(TARGET softfloat PROPERTY C_STANDARD 99)
|
set_property(TARGET softfloat PROPERTY C_STANDARD 99)
|
||||||
target_compile_definitions(softfloat PRIVATE
|
target_compile_definitions(softfloat PRIVATE
|
||||||
SOFTFLOAT_ROUND_ODD
|
SOFTFLOAT_ROUND_ODD
|
||||||
@@ -347,7 +347,7 @@ set_target_properties(softfloat PROPERTIES
|
|||||||
|
|
||||||
install(TARGETS softfloat
|
install(TARGETS softfloat
|
||||||
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/static COMPONENT libs # static lib
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib
|
||||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # for mac
|
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # for mac
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel # headers for mac (note the different component -> different package)
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT devel # headers for mac (note the different component -> different package)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
Package Overview for Berkeley SoftFloat Release 3e
|
||||||
|
==================================================
|
||||||
|
|
||||||
|
John R. Hauser<br>
|
||||||
|
2018 January 20
|
||||||
|
|
||||||
|
|
||||||
|
Berkeley SoftFloat is a software implementation of binary floating-point
|
||||||
|
that conforms to the IEEE Standard for Floating-Point Arithmetic. SoftFloat
|
||||||
|
is distributed in the form of C source code. Building the SoftFloat sources
|
||||||
|
generates a library file (typically `softfloat.a` or `libsoftfloat.a`)
|
||||||
|
containing the floating-point subroutines.
|
||||||
|
|
||||||
|
|
||||||
|
The SoftFloat package is documented in the following files in the `doc`
|
||||||
|
subdirectory:
|
||||||
|
|
||||||
|
* [SoftFloat.html](http://www.jhauser.us/arithmetic/SoftFloat-3/doc/SoftFloat.html) Documentation for using the SoftFloat functions.
|
||||||
|
* [SoftFloat-source.html](http://www.jhauser.us/arithmetic/SoftFloat-3/doc/SoftFloat-source.html) Documentation for building SoftFloat.
|
||||||
|
* [SoftFloat-history.html](http://www.jhauser.us/arithmetic/SoftFloat-3/doc/SoftFloat-history.html) History of the major changes to SoftFloat.
|
||||||
|
|
||||||
|
Other files in the package comprise the source code for SoftFloat.
|
||||||
|
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
#
|
||||||
|
# This Makefile is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
# Package, Release 3e, by John R. Hauser.
|
||||||
|
#
|
||||||
|
# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
|
||||||
|
# University of California. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions, and the following disclaimer.
|
||||||
|
#
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions, and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
#
|
||||||
|
# 3. Neither the name of the University nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
SOURCE_DIR ?= ../../source
|
||||||
|
SPECIALIZE_TYPE ?= RISCV
|
||||||
|
MARCH ?= rv64gcv_zfh_zfhmin
|
||||||
|
MABI ?= lp64d
|
||||||
|
|
||||||
|
SOFTFLOAT_OPTS ?= \
|
||||||
|
-DSOFTFLOAT_ROUND_ODD -DINLINE_LEVEL=5 -DSOFTFLOAT_FAST_DIV32TO16 \
|
||||||
|
-DSOFTFLOAT_FAST_DIV64TO32
|
||||||
|
|
||||||
|
DELETE = rm -f
|
||||||
|
C_INCLUDES = -I. -I$(SOURCE_DIR)/$(SPECIALIZE_TYPE) -I$(SOURCE_DIR)/include
|
||||||
|
COMPILE_C = \
|
||||||
|
riscv64-unknown-linux-gnu-gcc -c -march=$(MARCH) -mabi=$(MABI) -Werror-implicit-function-declaration -DSOFTFLOAT_FAST_INT64 \
|
||||||
|
$(SOFTFLOAT_OPTS) $(C_INCLUDES) -O2 -o $@
|
||||||
|
MAKELIB = ar crs $@
|
||||||
|
|
||||||
|
OBJ = .o
|
||||||
|
LIB = .a
|
||||||
|
|
||||||
|
OTHER_HEADERS = $(SOURCE_DIR)/include/opts-GCC.h
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: softfloat$(LIB)
|
||||||
|
|
||||||
|
OBJS_PRIMITIVES = \
|
||||||
|
s_eq128$(OBJ) \
|
||||||
|
s_le128$(OBJ) \
|
||||||
|
s_lt128$(OBJ) \
|
||||||
|
s_shortShiftLeft128$(OBJ) \
|
||||||
|
s_shortShiftRight128$(OBJ) \
|
||||||
|
s_shortShiftRightJam64$(OBJ) \
|
||||||
|
s_shortShiftRightJam64Extra$(OBJ) \
|
||||||
|
s_shortShiftRightJam128$(OBJ) \
|
||||||
|
s_shortShiftRightJam128Extra$(OBJ) \
|
||||||
|
s_shiftRightJam32$(OBJ) \
|
||||||
|
s_shiftRightJam64$(OBJ) \
|
||||||
|
s_shiftRightJam64Extra$(OBJ) \
|
||||||
|
s_shiftRightJam128$(OBJ) \
|
||||||
|
s_shiftRightJam128Extra$(OBJ) \
|
||||||
|
s_shiftRightJam256M$(OBJ) \
|
||||||
|
s_countLeadingZeros8$(OBJ) \
|
||||||
|
s_countLeadingZeros16$(OBJ) \
|
||||||
|
s_countLeadingZeros32$(OBJ) \
|
||||||
|
s_countLeadingZeros64$(OBJ) \
|
||||||
|
s_add128$(OBJ) \
|
||||||
|
s_add256M$(OBJ) \
|
||||||
|
s_sub128$(OBJ) \
|
||||||
|
s_sub256M$(OBJ) \
|
||||||
|
s_mul64ByShifted32To128$(OBJ) \
|
||||||
|
s_mul64To128$(OBJ) \
|
||||||
|
s_mul128By32$(OBJ) \
|
||||||
|
s_mul128To256M$(OBJ) \
|
||||||
|
s_approxRecip_1Ks$(OBJ) \
|
||||||
|
s_approxRecip32_1$(OBJ) \
|
||||||
|
s_approxRecipSqrt_1Ks$(OBJ) \
|
||||||
|
s_approxRecipSqrt32_1$(OBJ) \
|
||||||
|
|
||||||
|
OBJS_SPECIALIZE = \
|
||||||
|
softfloat_raiseFlags$(OBJ) \
|
||||||
|
s_f16UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToF16UI$(OBJ) \
|
||||||
|
s_propagateNaNF16UI$(OBJ) \
|
||||||
|
s_bf16UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToBF16UI$(OBJ) \
|
||||||
|
s_f32UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToF32UI$(OBJ) \
|
||||||
|
s_propagateNaNF32UI$(OBJ) \
|
||||||
|
s_f64UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToF64UI$(OBJ) \
|
||||||
|
s_propagateNaNF64UI$(OBJ) \
|
||||||
|
extF80M_isSignalingNaN$(OBJ) \
|
||||||
|
s_extF80UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToExtF80UI$(OBJ) \
|
||||||
|
s_propagateNaNExtF80UI$(OBJ) \
|
||||||
|
f128M_isSignalingNaN$(OBJ) \
|
||||||
|
s_f128UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToF128UI$(OBJ) \
|
||||||
|
s_propagateNaNF128UI$(OBJ) \
|
||||||
|
|
||||||
|
OBJS_OTHERS = \
|
||||||
|
s_roundToUI32$(OBJ) \
|
||||||
|
s_roundToUI64$(OBJ) \
|
||||||
|
s_roundToI32$(OBJ) \
|
||||||
|
s_roundToI64$(OBJ) \
|
||||||
|
s_normSubnormalBF16Sig$(OBJ) \
|
||||||
|
s_roundPackToBF16$(OBJ) \
|
||||||
|
s_normSubnormalF16Sig$(OBJ) \
|
||||||
|
s_roundPackToF16$(OBJ) \
|
||||||
|
s_normRoundPackToF16$(OBJ) \
|
||||||
|
s_addMagsF16$(OBJ) \
|
||||||
|
s_subMagsF16$(OBJ) \
|
||||||
|
s_mulAddF16$(OBJ) \
|
||||||
|
s_normSubnormalF32Sig$(OBJ) \
|
||||||
|
s_roundPackToF32$(OBJ) \
|
||||||
|
s_normRoundPackToF32$(OBJ) \
|
||||||
|
s_addMagsF32$(OBJ) \
|
||||||
|
s_subMagsF32$(OBJ) \
|
||||||
|
s_mulAddF32$(OBJ) \
|
||||||
|
s_normSubnormalF64Sig$(OBJ) \
|
||||||
|
s_roundPackToF64$(OBJ) \
|
||||||
|
s_normRoundPackToF64$(OBJ) \
|
||||||
|
s_addMagsF64$(OBJ) \
|
||||||
|
s_subMagsF64$(OBJ) \
|
||||||
|
s_mulAddF64$(OBJ) \
|
||||||
|
s_normSubnormalExtF80Sig$(OBJ) \
|
||||||
|
s_roundPackToExtF80$(OBJ) \
|
||||||
|
s_normRoundPackToExtF80$(OBJ) \
|
||||||
|
s_addMagsExtF80$(OBJ) \
|
||||||
|
s_subMagsExtF80$(OBJ) \
|
||||||
|
s_normSubnormalF128Sig$(OBJ) \
|
||||||
|
s_roundPackToF128$(OBJ) \
|
||||||
|
s_normRoundPackToF128$(OBJ) \
|
||||||
|
s_addMagsF128$(OBJ) \
|
||||||
|
s_subMagsF128$(OBJ) \
|
||||||
|
s_mulAddF128$(OBJ) \
|
||||||
|
softfloat_state$(OBJ) \
|
||||||
|
ui32_to_f16$(OBJ) \
|
||||||
|
ui32_to_f32$(OBJ) \
|
||||||
|
ui32_to_f64$(OBJ) \
|
||||||
|
ui32_to_extF80$(OBJ) \
|
||||||
|
ui32_to_extF80M$(OBJ) \
|
||||||
|
ui32_to_f128$(OBJ) \
|
||||||
|
ui32_to_f128M$(OBJ) \
|
||||||
|
ui64_to_f16$(OBJ) \
|
||||||
|
ui64_to_f32$(OBJ) \
|
||||||
|
ui64_to_f64$(OBJ) \
|
||||||
|
ui64_to_extF80$(OBJ) \
|
||||||
|
ui64_to_extF80M$(OBJ) \
|
||||||
|
ui64_to_f128$(OBJ) \
|
||||||
|
ui64_to_f128M$(OBJ) \
|
||||||
|
i32_to_f16$(OBJ) \
|
||||||
|
i32_to_f32$(OBJ) \
|
||||||
|
i32_to_f64$(OBJ) \
|
||||||
|
i32_to_extF80$(OBJ) \
|
||||||
|
i32_to_extF80M$(OBJ) \
|
||||||
|
i32_to_f128$(OBJ) \
|
||||||
|
i32_to_f128M$(OBJ) \
|
||||||
|
i64_to_f16$(OBJ) \
|
||||||
|
i64_to_f32$(OBJ) \
|
||||||
|
i64_to_f64$(OBJ) \
|
||||||
|
i64_to_extF80$(OBJ) \
|
||||||
|
i64_to_extF80M$(OBJ) \
|
||||||
|
i64_to_f128$(OBJ) \
|
||||||
|
i64_to_f128M$(OBJ) \
|
||||||
|
bf16_isSignalingNaN$(OBJ) \
|
||||||
|
bf16_to_f32$(OBJ) \
|
||||||
|
f16_to_ui32$(OBJ) \
|
||||||
|
f16_to_ui64$(OBJ) \
|
||||||
|
f16_to_i32$(OBJ) \
|
||||||
|
f16_to_i64$(OBJ) \
|
||||||
|
f16_to_ui32_r_minMag$(OBJ) \
|
||||||
|
f16_to_ui64_r_minMag$(OBJ) \
|
||||||
|
f16_to_i32_r_minMag$(OBJ) \
|
||||||
|
f16_to_i64_r_minMag$(OBJ) \
|
||||||
|
f16_to_f32$(OBJ) \
|
||||||
|
f16_to_f64$(OBJ) \
|
||||||
|
f16_to_extF80$(OBJ) \
|
||||||
|
f16_to_extF80M$(OBJ) \
|
||||||
|
f16_to_f128$(OBJ) \
|
||||||
|
f16_to_f128M$(OBJ) \
|
||||||
|
f16_roundToInt$(OBJ) \
|
||||||
|
f16_add$(OBJ) \
|
||||||
|
f16_sub$(OBJ) \
|
||||||
|
f16_mul$(OBJ) \
|
||||||
|
f16_mulAdd$(OBJ) \
|
||||||
|
f16_div$(OBJ) \
|
||||||
|
f16_rem$(OBJ) \
|
||||||
|
f16_sqrt$(OBJ) \
|
||||||
|
f16_eq$(OBJ) \
|
||||||
|
f16_le$(OBJ) \
|
||||||
|
f16_lt$(OBJ) \
|
||||||
|
f16_eq_signaling$(OBJ) \
|
||||||
|
f16_le_quiet$(OBJ) \
|
||||||
|
f16_lt_quiet$(OBJ) \
|
||||||
|
f16_isSignalingNaN$(OBJ) \
|
||||||
|
f32_to_ui32$(OBJ) \
|
||||||
|
f32_to_ui64$(OBJ) \
|
||||||
|
f32_to_i32$(OBJ) \
|
||||||
|
f32_to_i64$(OBJ) \
|
||||||
|
f32_to_ui32_r_minMag$(OBJ) \
|
||||||
|
f32_to_ui64_r_minMag$(OBJ) \
|
||||||
|
f32_to_i32_r_minMag$(OBJ) \
|
||||||
|
f32_to_i64_r_minMag$(OBJ) \
|
||||||
|
f32_to_bf16$(OBJ) \
|
||||||
|
f32_to_f16$(OBJ) \
|
||||||
|
f32_to_f64$(OBJ) \
|
||||||
|
f32_to_extF80$(OBJ) \
|
||||||
|
f32_to_extF80M$(OBJ) \
|
||||||
|
f32_to_f128$(OBJ) \
|
||||||
|
f32_to_f128M$(OBJ) \
|
||||||
|
f32_roundToInt$(OBJ) \
|
||||||
|
f32_add$(OBJ) \
|
||||||
|
f32_sub$(OBJ) \
|
||||||
|
f32_mul$(OBJ) \
|
||||||
|
f32_mulAdd$(OBJ) \
|
||||||
|
f32_div$(OBJ) \
|
||||||
|
f32_rem$(OBJ) \
|
||||||
|
f32_sqrt$(OBJ) \
|
||||||
|
f32_eq$(OBJ) \
|
||||||
|
f32_le$(OBJ) \
|
||||||
|
f32_lt$(OBJ) \
|
||||||
|
f32_eq_signaling$(OBJ) \
|
||||||
|
f32_le_quiet$(OBJ) \
|
||||||
|
f32_lt_quiet$(OBJ) \
|
||||||
|
f32_isSignalingNaN$(OBJ) \
|
||||||
|
f64_to_ui32$(OBJ) \
|
||||||
|
f64_to_ui64$(OBJ) \
|
||||||
|
f64_to_i32$(OBJ) \
|
||||||
|
f64_to_i64$(OBJ) \
|
||||||
|
f64_to_ui32_r_minMag$(OBJ) \
|
||||||
|
f64_to_ui64_r_minMag$(OBJ) \
|
||||||
|
f64_to_i32_r_minMag$(OBJ) \
|
||||||
|
f64_to_i64_r_minMag$(OBJ) \
|
||||||
|
f64_to_f16$(OBJ) \
|
||||||
|
f64_to_f32$(OBJ) \
|
||||||
|
f64_to_extF80$(OBJ) \
|
||||||
|
f64_to_extF80M$(OBJ) \
|
||||||
|
f64_to_f128$(OBJ) \
|
||||||
|
f64_to_f128M$(OBJ) \
|
||||||
|
f64_roundToInt$(OBJ) \
|
||||||
|
f64_add$(OBJ) \
|
||||||
|
f64_sub$(OBJ) \
|
||||||
|
f64_mul$(OBJ) \
|
||||||
|
f64_mulAdd$(OBJ) \
|
||||||
|
f64_div$(OBJ) \
|
||||||
|
f64_rem$(OBJ) \
|
||||||
|
f64_sqrt$(OBJ) \
|
||||||
|
f64_eq$(OBJ) \
|
||||||
|
f64_le$(OBJ) \
|
||||||
|
f64_lt$(OBJ) \
|
||||||
|
f64_eq_signaling$(OBJ) \
|
||||||
|
f64_le_quiet$(OBJ) \
|
||||||
|
f64_lt_quiet$(OBJ) \
|
||||||
|
f64_isSignalingNaN$(OBJ) \
|
||||||
|
extF80_to_ui32$(OBJ) \
|
||||||
|
extF80_to_ui64$(OBJ) \
|
||||||
|
extF80_to_i32$(OBJ) \
|
||||||
|
extF80_to_i64$(OBJ) \
|
||||||
|
extF80_to_ui32_r_minMag$(OBJ) \
|
||||||
|
extF80_to_ui64_r_minMag$(OBJ) \
|
||||||
|
extF80_to_i32_r_minMag$(OBJ) \
|
||||||
|
extF80_to_i64_r_minMag$(OBJ) \
|
||||||
|
extF80_to_f16$(OBJ) \
|
||||||
|
extF80_to_f32$(OBJ) \
|
||||||
|
extF80_to_f64$(OBJ) \
|
||||||
|
extF80_to_f128$(OBJ) \
|
||||||
|
extF80_roundToInt$(OBJ) \
|
||||||
|
extF80_add$(OBJ) \
|
||||||
|
extF80_sub$(OBJ) \
|
||||||
|
extF80_mul$(OBJ) \
|
||||||
|
extF80_div$(OBJ) \
|
||||||
|
extF80_rem$(OBJ) \
|
||||||
|
extF80_sqrt$(OBJ) \
|
||||||
|
extF80_eq$(OBJ) \
|
||||||
|
extF80_le$(OBJ) \
|
||||||
|
extF80_lt$(OBJ) \
|
||||||
|
extF80_eq_signaling$(OBJ) \
|
||||||
|
extF80_le_quiet$(OBJ) \
|
||||||
|
extF80_lt_quiet$(OBJ) \
|
||||||
|
extF80_isSignalingNaN$(OBJ) \
|
||||||
|
extF80M_to_ui32$(OBJ) \
|
||||||
|
extF80M_to_ui64$(OBJ) \
|
||||||
|
extF80M_to_i32$(OBJ) \
|
||||||
|
extF80M_to_i64$(OBJ) \
|
||||||
|
extF80M_to_ui32_r_minMag$(OBJ) \
|
||||||
|
extF80M_to_ui64_r_minMag$(OBJ) \
|
||||||
|
extF80M_to_i32_r_minMag$(OBJ) \
|
||||||
|
extF80M_to_i64_r_minMag$(OBJ) \
|
||||||
|
extF80M_to_f16$(OBJ) \
|
||||||
|
extF80M_to_f32$(OBJ) \
|
||||||
|
extF80M_to_f64$(OBJ) \
|
||||||
|
extF80M_to_f128M$(OBJ) \
|
||||||
|
extF80M_roundToInt$(OBJ) \
|
||||||
|
extF80M_add$(OBJ) \
|
||||||
|
extF80M_sub$(OBJ) \
|
||||||
|
extF80M_mul$(OBJ) \
|
||||||
|
extF80M_div$(OBJ) \
|
||||||
|
extF80M_rem$(OBJ) \
|
||||||
|
extF80M_sqrt$(OBJ) \
|
||||||
|
extF80M_eq$(OBJ) \
|
||||||
|
extF80M_le$(OBJ) \
|
||||||
|
extF80M_lt$(OBJ) \
|
||||||
|
extF80M_eq_signaling$(OBJ) \
|
||||||
|
extF80M_le_quiet$(OBJ) \
|
||||||
|
extF80M_lt_quiet$(OBJ) \
|
||||||
|
f128_to_ui32$(OBJ) \
|
||||||
|
f128_to_ui64$(OBJ) \
|
||||||
|
f128_to_i32$(OBJ) \
|
||||||
|
f128_to_i64$(OBJ) \
|
||||||
|
f128_to_ui32_r_minMag$(OBJ) \
|
||||||
|
f128_to_ui64_r_minMag$(OBJ) \
|
||||||
|
f128_to_i32_r_minMag$(OBJ) \
|
||||||
|
f128_to_i64_r_minMag$(OBJ) \
|
||||||
|
f128_to_f16$(OBJ) \
|
||||||
|
f128_to_f32$(OBJ) \
|
||||||
|
f128_to_extF80$(OBJ) \
|
||||||
|
f128_to_f64$(OBJ) \
|
||||||
|
f128_roundToInt$(OBJ) \
|
||||||
|
f128_add$(OBJ) \
|
||||||
|
f128_sub$(OBJ) \
|
||||||
|
f128_mul$(OBJ) \
|
||||||
|
f128_mulAdd$(OBJ) \
|
||||||
|
f128_div$(OBJ) \
|
||||||
|
f128_rem$(OBJ) \
|
||||||
|
f128_sqrt$(OBJ) \
|
||||||
|
f128_eq$(OBJ) \
|
||||||
|
f128_le$(OBJ) \
|
||||||
|
f128_lt$(OBJ) \
|
||||||
|
f128_eq_signaling$(OBJ) \
|
||||||
|
f128_le_quiet$(OBJ) \
|
||||||
|
f128_lt_quiet$(OBJ) \
|
||||||
|
f128_isSignalingNaN$(OBJ) \
|
||||||
|
f128M_to_ui32$(OBJ) \
|
||||||
|
f128M_to_ui64$(OBJ) \
|
||||||
|
f128M_to_i32$(OBJ) \
|
||||||
|
f128M_to_i64$(OBJ) \
|
||||||
|
f128M_to_ui32_r_minMag$(OBJ) \
|
||||||
|
f128M_to_ui64_r_minMag$(OBJ) \
|
||||||
|
f128M_to_i32_r_minMag$(OBJ) \
|
||||||
|
f128M_to_i64_r_minMag$(OBJ) \
|
||||||
|
f128M_to_f16$(OBJ) \
|
||||||
|
f128M_to_f32$(OBJ) \
|
||||||
|
f128M_to_extF80M$(OBJ) \
|
||||||
|
f128M_to_f64$(OBJ) \
|
||||||
|
f128M_roundToInt$(OBJ) \
|
||||||
|
f128M_add$(OBJ) \
|
||||||
|
f128M_sub$(OBJ) \
|
||||||
|
f128M_mul$(OBJ) \
|
||||||
|
f128M_mulAdd$(OBJ) \
|
||||||
|
f128M_div$(OBJ) \
|
||||||
|
f128M_rem$(OBJ) \
|
||||||
|
f128M_sqrt$(OBJ) \
|
||||||
|
f128M_eq$(OBJ) \
|
||||||
|
f128M_le$(OBJ) \
|
||||||
|
f128M_lt$(OBJ) \
|
||||||
|
f128M_eq_signaling$(OBJ) \
|
||||||
|
f128M_le_quiet$(OBJ) \
|
||||||
|
f128M_lt_quiet$(OBJ) \
|
||||||
|
|
||||||
|
OBJS_ALL = $(OBJS_PRIMITIVES) $(OBJS_SPECIALIZE) $(OBJS_OTHERS)
|
||||||
|
|
||||||
|
$(OBJS_ALL): \
|
||||||
|
$(OTHER_HEADERS) platform.h $(SOURCE_DIR)/include/primitiveTypes.h \
|
||||||
|
$(SOURCE_DIR)/include/primitives.h
|
||||||
|
$(OBJS_SPECIALIZE) $(OBJS_OTHERS): \
|
||||||
|
$(SOURCE_DIR)/include/softfloat_types.h $(SOURCE_DIR)/include/internals.h \
|
||||||
|
$(SOURCE_DIR)/$(SPECIALIZE_TYPE)/specialize.h \
|
||||||
|
$(SOURCE_DIR)/include/softfloat.h
|
||||||
|
|
||||||
|
$(OBJS_PRIMITIVES) $(OBJS_OTHERS): %$(OBJ): $(SOURCE_DIR)/%.c
|
||||||
|
$(COMPILE_C) $(SOURCE_DIR)/$*.c
|
||||||
|
|
||||||
|
$(OBJS_SPECIALIZE): %$(OBJ): $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/%.c
|
||||||
|
$(COMPILE_C) $(SOURCE_DIR)/$(SPECIALIZE_TYPE)/$*.c
|
||||||
|
|
||||||
|
softfloat$(LIB): $(OBJS_ALL)
|
||||||
|
$(DELETE) $@
|
||||||
|
$(MAKELIB) $^
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
$(DELETE) $(OBJS_ALL) softfloat$(LIB)
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the
|
||||||
|
University of California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define LITTLEENDIAN 1
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#ifdef __GNUC_STDC_INLINE__
|
||||||
|
#define INLINE inline
|
||||||
|
#else
|
||||||
|
#define INLINE extern inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define SOFTFLOAT_BUILTIN_CLZ 1
|
||||||
|
#define SOFTFLOAT_INTRINSIC_INT128 1
|
||||||
|
#include "opts-GCC.h"
|
||||||
|
|
||||||
@@ -94,6 +94,8 @@ OBJS_SPECIALIZE = \
|
|||||||
s_f16UIToCommonNaN$(OBJ) \
|
s_f16UIToCommonNaN$(OBJ) \
|
||||||
s_commonNaNToF16UI$(OBJ) \
|
s_commonNaNToF16UI$(OBJ) \
|
||||||
s_propagateNaNF16UI$(OBJ) \
|
s_propagateNaNF16UI$(OBJ) \
|
||||||
|
s_bf16UIToCommonNaN$(OBJ) \
|
||||||
|
s_commonNaNToBF16UI$(OBJ) \
|
||||||
s_f32UIToCommonNaN$(OBJ) \
|
s_f32UIToCommonNaN$(OBJ) \
|
||||||
s_commonNaNToF32UI$(OBJ) \
|
s_commonNaNToF32UI$(OBJ) \
|
||||||
s_propagateNaNF32UI$(OBJ) \
|
s_propagateNaNF32UI$(OBJ) \
|
||||||
@@ -114,6 +116,8 @@ OBJS_OTHERS = \
|
|||||||
s_roundToUI64$(OBJ) \
|
s_roundToUI64$(OBJ) \
|
||||||
s_roundToI32$(OBJ) \
|
s_roundToI32$(OBJ) \
|
||||||
s_roundToI64$(OBJ) \
|
s_roundToI64$(OBJ) \
|
||||||
|
s_normSubnormalBF16Sig$(OBJ) \
|
||||||
|
s_roundPackToBF16$(OBJ) \
|
||||||
s_normSubnormalF16Sig$(OBJ) \
|
s_normSubnormalF16Sig$(OBJ) \
|
||||||
s_roundPackToF16$(OBJ) \
|
s_roundPackToF16$(OBJ) \
|
||||||
s_normRoundPackToF16$(OBJ) \
|
s_normRoundPackToF16$(OBJ) \
|
||||||
@@ -172,6 +176,8 @@ OBJS_OTHERS = \
|
|||||||
i64_to_extF80M$(OBJ) \
|
i64_to_extF80M$(OBJ) \
|
||||||
i64_to_f128$(OBJ) \
|
i64_to_f128$(OBJ) \
|
||||||
i64_to_f128M$(OBJ) \
|
i64_to_f128M$(OBJ) \
|
||||||
|
bf16_isSignalingNaN$(OBJ) \
|
||||||
|
bf16_to_f32$(OBJ) \
|
||||||
f16_to_ui32$(OBJ) \
|
f16_to_ui32$(OBJ) \
|
||||||
f16_to_ui64$(OBJ) \
|
f16_to_ui64$(OBJ) \
|
||||||
f16_to_i32$(OBJ) \
|
f16_to_i32$(OBJ) \
|
||||||
@@ -209,6 +215,7 @@ OBJS_OTHERS = \
|
|||||||
f32_to_ui64_r_minMag$(OBJ) \
|
f32_to_ui64_r_minMag$(OBJ) \
|
||||||
f32_to_i32_r_minMag$(OBJ) \
|
f32_to_i32_r_minMag$(OBJ) \
|
||||||
f32_to_i64_r_minMag$(OBJ) \
|
f32_to_i64_r_minMag$(OBJ) \
|
||||||
|
f32_to_bf16$(OBJ) \
|
||||||
f32_to_f16$(OBJ) \
|
f32_to_f16$(OBJ) \
|
||||||
f32_to_f64$(OBJ) \
|
f32_to_f64$(OBJ) \
|
||||||
f32_to_extF80$(OBJ) \
|
f32_to_extF80$(OBJ) \
|
||||||
|
|||||||
@@ -54,4 +54,3 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define SOFTFLOAT_INTRINSIC_INT128 1
|
#define SOFTFLOAT_INTRINSIC_INT128 1
|
||||||
#endif
|
#endif
|
||||||
#include "opts-GCC.h"
|
#include "opts-GCC.h"
|
||||||
|
|
||||||
@@ -115,6 +115,8 @@ OBJS_OTHERS = \
|
|||||||
s_roundToUI64$(OBJ) \
|
s_roundToUI64$(OBJ) \
|
||||||
s_roundToI32$(OBJ) \
|
s_roundToI32$(OBJ) \
|
||||||
s_roundToI64$(OBJ) \
|
s_roundToI64$(OBJ) \
|
||||||
|
s_normSubnormalBF16Sig$(OBJ) \
|
||||||
|
s_roundPackToBF16$(OBJ) \
|
||||||
s_normSubnormalF16Sig$(OBJ) \
|
s_normSubnormalF16Sig$(OBJ) \
|
||||||
s_roundPackToF16$(OBJ) \
|
s_roundPackToF16$(OBJ) \
|
||||||
s_normRoundPackToF16$(OBJ) \
|
s_normRoundPackToF16$(OBJ) \
|
||||||
@@ -173,6 +175,8 @@ OBJS_OTHERS = \
|
|||||||
i64_to_extF80M$(OBJ) \
|
i64_to_extF80M$(OBJ) \
|
||||||
i64_to_f128$(OBJ) \
|
i64_to_f128$(OBJ) \
|
||||||
i64_to_f128M$(OBJ) \
|
i64_to_f128M$(OBJ) \
|
||||||
|
bf16_isSignalingNaN$(OBJ) \
|
||||||
|
bf16_to_f32$(OBJ) \
|
||||||
f16_to_ui32$(OBJ) \
|
f16_to_ui32$(OBJ) \
|
||||||
f16_to_ui64$(OBJ) \
|
f16_to_ui64$(OBJ) \
|
||||||
f16_to_i32$(OBJ) \
|
f16_to_i32$(OBJ) \
|
||||||
@@ -210,6 +214,7 @@ OBJS_OTHERS = \
|
|||||||
f32_to_ui64_r_minMag$(OBJ) \
|
f32_to_ui64_r_minMag$(OBJ) \
|
||||||
f32_to_i32_r_minMag$(OBJ) \
|
f32_to_i32_r_minMag$(OBJ) \
|
||||||
f32_to_i64_r_minMag$(OBJ) \
|
f32_to_i64_r_minMag$(OBJ) \
|
||||||
|
f32_to_bf16$(OBJ) \
|
||||||
f32_to_f16$(OBJ) \
|
f32_to_f16$(OBJ) \
|
||||||
f32_to_f64$(OBJ) \
|
f32_to_f64$(OBJ) \
|
||||||
f32_to_extF80$(OBJ) \
|
f32_to_extF80$(OBJ) \
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ significant extra cost.
|
|||||||
On computers where the word size is <NOBR>64 bits</NOBR> or larger, both
|
On computers where the word size is <NOBR>64 bits</NOBR> or larger, both
|
||||||
function versions (<CODE>f128M_add</CODE> and <CODE>f128_add</CODE>) are
|
function versions (<CODE>f128M_add</CODE> and <CODE>f128_add</CODE>) are
|
||||||
provided, because the cost of passing by value is then more reasonable.
|
provided, because the cost of passing by value is then more reasonable.
|
||||||
Applications that must be portable accross both classes of computers must use
|
Applications that must be portable across both classes of computers must use
|
||||||
the pointer-based functions, as these are always implemented.
|
the pointer-based functions, as these are always implemented.
|
||||||
However, if it is known that SoftFloat includes the by-value functions for all
|
However, if it is known that SoftFloat includes the by-value functions for all
|
||||||
platforms of interest, programmers can use whichever version they prefer.
|
platforms of interest, programmers can use whichever version they prefer.
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Assuming `uiA' has the bit pattern of a BF16 NaN, converts
|
||||||
|
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
||||||
|
| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
|
| exception is raised.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void softfloat_bf16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( softfloat_isSigNaNBF16UI( uiA ) ) {
|
||||||
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
|
}
|
||||||
|
zPtr->sign = uiA>>15;
|
||||||
|
zPtr->v64 = (uint_fast64_t) uiA<<56;
|
||||||
|
zPtr->v0 = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Converts the common NaN pointed to by `aPtr' into a BF16 NaN, and
|
||||||
|
| returns the bit pattern of this value as an unsigned integer.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
uint_fast16_t softfloat_commonNaNToBF16UI( const struct commonNaN *aPtr )
|
||||||
|
{
|
||||||
|
|
||||||
|
return (uint_fast16_t) aPtr->sign<<15 | 0x7FC0 | aPtr->v64>>56;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef specialize_h
|
#ifndef specialize_h
|
||||||
#define specialize_h 1
|
#define specialize_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Default value for 'softfloat_detectTininess'.
|
| Default value for 'softfloat_detectTininess'.
|
||||||
@@ -114,8 +114,28 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t
|
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a
|
||||||
|
| 16-bit brain floating-point (BF16) signaling NaN.
|
||||||
|
| Note: This macro evaluates its argument more than once.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define softfloat_isSigNaNBF16UI(uiA) ((((uiA)&0x7FC0) == 0x7F80) && ((uiA)&0x003F))
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Assuming 'uiA' has the bit pattern of a 16-bit BF16 floating-point NaN, converts
|
||||||
|
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
||||||
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
|
| exception is raised.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
void softfloat_bf16UIToCommonNaN(uint_fast16_t uiA, struct commonNaN* zPtr);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
||||||
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
uint_fast16_t softfloat_commonNaNToBF16UI(const struct commonNaN* aPtr);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 32-bit floating-point NaN.
|
| The bit pattern for a default generated 32-bit floating-point NaN.
|
||||||
@@ -149,8 +169,7 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t
|
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 64-bit floating-point NaN.
|
| The bit pattern for a default generated 64-bit floating-point NaN.
|
||||||
@@ -162,7 +181,8 @@ uint_fast32_t
|
|||||||
| 64-bit floating-point signaling NaN.
|
| 64-bit floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its argument more than once.
|
| Note: This macro evaluates its argument more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))
|
#define softfloat_isSigNaNF64UI(uiA) \
|
||||||
|
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
||||||
@@ -184,8 +204,7 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
||||||
@@ -199,7 +218,8 @@ uint_fast64_t
|
|||||||
| floating-point signaling NaN.
|
| floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))
|
#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
@@ -215,9 +235,7 @@ uint_fast64_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_extF80UIToCommonNaN(
|
|
||||||
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
@@ -235,13 +253,7 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
|
|||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
| invalid exception is raised.
|
| invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNExtF80UI(
|
|
||||||
uint_fast16_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast16_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -255,7 +267,8 @@ struct uint128
|
|||||||
| point signaling NaN.
|
| point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))
|
#define softfloat_isSigNaNF128UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
||||||
@@ -264,9 +277,7 @@ struct uint128
|
|||||||
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
||||||
| is raised.
|
| is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_f128UIToCommonNaN(
|
|
||||||
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -283,13 +294,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
|
|||||||
| If either original floating-point value is a signaling NaN, the invalid
|
| If either original floating-point value is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNF128UI(
|
|
||||||
uint_fast64_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast64_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -304,18 +309,14 @@ struct uint128
|
|||||||
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
||||||
| NaN, the invalid exception is raised.
|
| NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
|
||||||
softfloat_extF80MToCommonNaN(
|
|
||||||
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
| floating-point NaN, and stores this NaN at the location pointed to by
|
| floating-point NaN, and stores this NaN at the location pointed to by
|
||||||
| 'zSPtr'.
|
| 'zSPtr'.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_commonNaNToExtF80M(
|
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 80-bit extended floating-point values
|
| Assuming at least one of the two 80-bit extended floating-point values
|
||||||
@@ -323,12 +324,7 @@ void
|
|||||||
| at the location pointed to by 'zSPtr'. If either original floating-point
|
| at the location pointed to by 'zSPtr'. If either original floating-point
|
||||||
| value is a signaling NaN, the invalid exception is raised.
|
| value is a signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_propagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *aSPtr,
|
|
||||||
const struct extFloat80M *bSPtr,
|
|
||||||
struct extFloat80M *zSPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -346,8 +342,7 @@ void
|
|||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
| four 32-bit elements that concatenate in the platform's normal endian order
|
||||||
| to form a 128-bit floating-point value.
|
| to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
|
||||||
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -355,8 +350,7 @@ void
|
|||||||
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form a 128-bit floating-point value.
|
| platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
||||||
@@ -366,11 +360,8 @@ void
|
|||||||
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
|
||||||
softfloat_propagateNaNF128M(
|
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef specialize_h
|
#ifndef specialize_h
|
||||||
#define specialize_h 1
|
#define specialize_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Default value for 'softfloat_detectTininess'.
|
| Default value for 'softfloat_detectTininess'.
|
||||||
@@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t
|
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 32-bit floating-point NaN.
|
| The bit pattern for a default generated 32-bit floating-point NaN.
|
||||||
@@ -149,8 +148,7 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t
|
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 64-bit floating-point NaN.
|
| The bit pattern for a default generated 64-bit floating-point NaN.
|
||||||
@@ -162,7 +160,8 @@ uint_fast32_t
|
|||||||
| 64-bit floating-point signaling NaN.
|
| 64-bit floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its argument more than once.
|
| Note: This macro evaluates its argument more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))
|
#define softfloat_isSigNaNF64UI(uiA) \
|
||||||
|
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
||||||
@@ -184,8 +183,7 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
||||||
@@ -199,7 +197,8 @@ uint_fast64_t
|
|||||||
| floating-point signaling NaN.
|
| floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))
|
#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
@@ -215,9 +214,7 @@ uint_fast64_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_extF80UIToCommonNaN(
|
|
||||||
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
@@ -235,13 +232,7 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
|
|||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
| invalid exception is raised.
|
| invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNExtF80UI(
|
|
||||||
uint_fast16_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast16_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -255,7 +246,8 @@ struct uint128
|
|||||||
| point signaling NaN.
|
| point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))
|
#define softfloat_isSigNaNF128UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
||||||
@@ -264,9 +256,7 @@ struct uint128
|
|||||||
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
||||||
| is raised.
|
| is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_f128UIToCommonNaN(
|
|
||||||
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
|
|||||||
| If either original floating-point value is a signaling NaN, the invalid
|
| If either original floating-point value is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNF128UI(
|
|
||||||
uint_fast64_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast64_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -304,18 +288,14 @@ struct uint128
|
|||||||
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
||||||
| NaN, the invalid exception is raised.
|
| NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
|
||||||
softfloat_extF80MToCommonNaN(
|
|
||||||
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
| floating-point NaN, and stores this NaN at the location pointed to by
|
| floating-point NaN, and stores this NaN at the location pointed to by
|
||||||
| 'zSPtr'.
|
| 'zSPtr'.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_commonNaNToExtF80M(
|
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 80-bit extended floating-point values
|
| Assuming at least one of the two 80-bit extended floating-point values
|
||||||
@@ -323,12 +303,7 @@ void
|
|||||||
| at the location pointed to by 'zSPtr'. If either original floating-point
|
| at the location pointed to by 'zSPtr'. If either original floating-point
|
||||||
| value is a signaling NaN, the invalid exception is raised.
|
| value is a signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_propagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *aSPtr,
|
|
||||||
const struct extFloat80M *bSPtr,
|
|
||||||
struct extFloat80M *zSPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -346,8 +321,7 @@ void
|
|||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
| four 32-bit elements that concatenate in the platform's normal endian order
|
||||||
| to form a 128-bit floating-point value.
|
| to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
|
||||||
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -355,8 +329,7 @@ void
|
|||||||
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form a 128-bit floating-point value.
|
| platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
||||||
@@ -366,11 +339,8 @@ void
|
|||||||
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
|
||||||
softfloat_propagateNaNF128M(
|
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef specialize_h
|
#ifndef specialize_h
|
||||||
#define specialize_h 1
|
#define specialize_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Default value for 'softfloat_detectTininess'.
|
| Default value for 'softfloat_detectTininess'.
|
||||||
@@ -73,7 +73,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| "Common NaN" structure, used to transfer NaN representations from one format
|
| "Common NaN" structure, used to transfer NaN representations from one format
|
||||||
| to another.
|
| to another.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct commonNaN { char _unused; };
|
struct commonNaN {
|
||||||
|
char _unused;
|
||||||
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 16-bit floating-point NaN.
|
| The bit pattern for a default generated 16-bit floating-point NaN.
|
||||||
@@ -93,7 +95,9 @@ struct commonNaN { char _unused; };
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_f16UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x0200) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_f16UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&0x0200)) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
||||||
@@ -107,8 +111,7 @@ struct commonNaN { char _unused; };
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t
|
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 32-bit floating-point NaN.
|
| The bit pattern for a default generated 32-bit floating-point NaN.
|
||||||
@@ -128,7 +131,9 @@ uint_fast16_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_f32UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&0x00400000)) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
|
||||||
@@ -142,8 +147,7 @@ uint_fast16_t
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t
|
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 64-bit floating-point NaN.
|
| The bit pattern for a default generated 64-bit floating-point NaN.
|
||||||
@@ -155,7 +159,8 @@ uint_fast32_t
|
|||||||
| 64-bit floating-point signaling NaN.
|
| 64-bit floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its argument more than once.
|
| Note: This macro evaluates its argument more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))
|
#define softfloat_isSigNaNF64UI(uiA) \
|
||||||
|
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
||||||
@@ -163,7 +168,9 @@ uint_fast32_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_f64UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&UINT64_C(0x0008000000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
|
||||||
@@ -177,8 +184,7 @@ uint_fast32_t
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
||||||
@@ -192,7 +198,8 @@ uint_fast64_t
|
|||||||
| floating-point signaling NaN.
|
| floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))
|
#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
@@ -208,7 +215,9 @@ uint_fast64_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_extF80UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA0) & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_extF80UIToCommonNaN(uiA64, uiA0, zPtr) \
|
||||||
|
if(!((uiA0)&UINT64_C(0x4000000000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
@@ -217,8 +226,7 @@ uint_fast64_t
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE && !defined softfloat_commonNaNToExtF80UI
|
#if defined INLINE && !defined softfloat_commonNaNToExtF80UI
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr )
|
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr) {
|
||||||
{
|
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
uiZ.v64 = defaultNaNExtF80UI64;
|
uiZ.v64 = defaultNaNExtF80UI64;
|
||||||
uiZ.v0 = defaultNaNExtF80UI0;
|
uiZ.v0 = defaultNaNExtF80UI0;
|
||||||
@@ -237,13 +245,7 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
|
|||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
| invalid exception is raised.
|
| invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNExtF80UI(
|
|
||||||
uint_fast16_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast16_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -257,7 +259,8 @@ struct uint128
|
|||||||
| point signaling NaN.
|
| point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))
|
#define softfloat_isSigNaNF128UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
||||||
@@ -266,7 +269,9 @@ struct uint128
|
|||||||
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
||||||
| is raised.
|
| is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_f128UIToCommonNaN(uiA64, uiA0, zPtr) \
|
||||||
|
if(!((uiA64)&UINT64_C(0x0000800000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -274,8 +279,7 @@ struct uint128
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE && !defined softfloat_commonNaNToF128UI
|
#if defined INLINE && !defined softfloat_commonNaNToF128UI
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )
|
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN* aPtr) {
|
||||||
{
|
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
uiZ.v64 = defaultNaNF128UI64;
|
uiZ.v64 = defaultNaNF128UI64;
|
||||||
uiZ.v0 = defaultNaNF128UI0;
|
uiZ.v0 = defaultNaNF128UI0;
|
||||||
@@ -294,13 +298,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
|
|||||||
| If either original floating-point value is a signaling NaN, the invalid
|
| If either original floating-point value is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNF128UI(
|
|
||||||
uint_fast64_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast64_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -315,7 +313,9 @@ struct uint128
|
|||||||
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
||||||
| NaN, the invalid exception is raised.
|
| NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_extF80MToCommonNaN( aSPtr, zPtr ) if ( ! ((aSPtr)->signif & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_extF80MToCommonNaN(aSPtr, zPtr) \
|
||||||
|
if(!((aSPtr)->signif & UINT64_C(0x4000000000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
@@ -324,17 +324,12 @@ struct uint128
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE && !defined softfloat_commonNaNToExtF80M
|
#if defined INLINE && !defined softfloat_commonNaNToExtF80M
|
||||||
INLINE
|
INLINE
|
||||||
void
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr) {
|
||||||
softfloat_commonNaNToExtF80M(
|
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr )
|
|
||||||
{
|
|
||||||
zSPtr->signExp = defaultNaNExtF80UI64;
|
zSPtr->signExp = defaultNaNExtF80UI64;
|
||||||
zSPtr->signif = defaultNaNExtF80UI0;
|
zSPtr->signif = defaultNaNExtF80UI0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_commonNaNToExtF80M(
|
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -343,12 +338,7 @@ void
|
|||||||
| at the location pointed to by 'zSPtr'. If either original floating-point
|
| at the location pointed to by 'zSPtr'. If either original floating-point
|
||||||
| value is a signaling NaN, the invalid exception is raised.
|
| value is a signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_propagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *aSPtr,
|
|
||||||
const struct extFloat80M *bSPtr,
|
|
||||||
struct extFloat80M *zSPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -366,7 +356,9 @@ void
|
|||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
| four 32-bit elements that concatenate in the platform's normal endian order
|
||||||
| to form a 128-bit floating-point value.
|
| to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_f128MToCommonNaN( aWPtr, zPtr ) if ( ! ((aWPtr)[indexWordHi( 4 )] & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid )
|
#define softfloat_f128MToCommonNaN(aWPtr, zPtr) \
|
||||||
|
if(!((aWPtr)[indexWordHi(4)] & UINT64_C(0x0000800000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -376,17 +368,14 @@ void
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE && !defined softfloat_commonNaNToF128M
|
#if defined INLINE && !defined softfloat_commonNaNToF128M
|
||||||
INLINE
|
INLINE
|
||||||
void
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr) {
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr )
|
|
||||||
{
|
|
||||||
zWPtr[indexWord(4, 3)] = defaultNaNF128UI96;
|
zWPtr[indexWord(4, 3)] = defaultNaNF128UI96;
|
||||||
zWPtr[indexWord(4, 2)] = defaultNaNF128UI64;
|
zWPtr[indexWord(4, 2)] = defaultNaNF128UI64;
|
||||||
zWPtr[indexWord(4, 1)] = defaultNaNF128UI32;
|
zWPtr[indexWord(4, 1)] = defaultNaNF128UI32;
|
||||||
zWPtr[indexWord(4, 0)] = defaultNaNF128UI0;
|
zWPtr[indexWord(4, 0)] = defaultNaNF128UI0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -397,11 +386,8 @@ void
|
|||||||
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
|
||||||
softfloat_propagateNaNF128M(
|
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef specialize_h
|
#ifndef specialize_h
|
||||||
#define specialize_h 1
|
#define specialize_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Default value for 'softfloat_detectTininess'.
|
| Default value for 'softfloat_detectTininess'.
|
||||||
@@ -114,8 +114,7 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t
|
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 32-bit floating-point NaN.
|
| The bit pattern for a default generated 32-bit floating-point NaN.
|
||||||
@@ -149,8 +148,7 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t
|
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 64-bit floating-point NaN.
|
| The bit pattern for a default generated 64-bit floating-point NaN.
|
||||||
@@ -162,7 +160,8 @@ uint_fast32_t
|
|||||||
| 64-bit floating-point signaling NaN.
|
| 64-bit floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its argument more than once.
|
| Note: This macro evaluates its argument more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))
|
#define softfloat_isSigNaNF64UI(uiA) \
|
||||||
|
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
||||||
@@ -184,8 +183,7 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
||||||
@@ -199,7 +197,8 @@ uint_fast64_t
|
|||||||
| floating-point signaling NaN.
|
| floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))
|
#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
@@ -215,9 +214,7 @@ uint_fast64_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80UIToCommonNaN(uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_extF80UIToCommonNaN(
|
|
||||||
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
@@ -235,13 +232,7 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
|
|||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
| invalid exception is raised.
|
| invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNExtF80UI(
|
|
||||||
uint_fast16_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast16_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -255,7 +246,8 @@ struct uint128
|
|||||||
| point signaling NaN.
|
| point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))
|
#define softfloat_isSigNaNF128UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
||||||
@@ -264,9 +256,7 @@ struct uint128
|
|||||||
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
||||||
| is raised.
|
| is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128UIToCommonNaN(uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN* zPtr);
|
||||||
softfloat_f128UIToCommonNaN(
|
|
||||||
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
|
|||||||
| If either original floating-point value is a signaling NaN, the invalid
|
| If either original floating-point value is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNF128UI(
|
|
||||||
uint_fast64_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast64_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -304,18 +288,14 @@ struct uint128
|
|||||||
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
||||||
| NaN, the invalid exception is raised.
|
| NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
|
||||||
softfloat_extF80MToCommonNaN(
|
|
||||||
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
| floating-point NaN, and stores this NaN at the location pointed to by
|
| floating-point NaN, and stores this NaN at the location pointed to by
|
||||||
| 'zSPtr'.
|
| 'zSPtr'.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_commonNaNToExtF80M(
|
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 80-bit extended floating-point values
|
| Assuming at least one of the two 80-bit extended floating-point values
|
||||||
@@ -323,12 +303,7 @@ void
|
|||||||
| at the location pointed to by 'zSPtr'. If either original floating-point
|
| at the location pointed to by 'zSPtr'. If either original floating-point
|
||||||
| value is a signaling NaN, the invalid exception is raised.
|
| value is a signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_propagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *aSPtr,
|
|
||||||
const struct extFloat80M *bSPtr,
|
|
||||||
struct extFloat80M *zSPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
@@ -346,8 +321,7 @@ void
|
|||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
| four 32-bit elements that concatenate in the platform's normal endian order
|
||||||
| to form a 128-bit floating-point value.
|
| to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
|
||||||
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -355,8 +329,7 @@ void
|
|||||||
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form a 128-bit floating-point value.
|
| platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
||||||
@@ -366,11 +339,8 @@ void
|
|||||||
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
|
||||||
softfloat_propagateNaNF128M(
|
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| This file intentionally contains no code.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| This file intentionally contains no code.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,9 +34,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
#include "softfloat_types.h"
|
||||||
|
|
||||||
|
#define softfloat_commonNaNToExtF80M softfloat_commonNaNToExtF80M
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -49,8 +50,8 @@ void
|
|||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr )
|
const struct commonNaN *aPtr, struct extFloat80M *zSPtr )
|
||||||
{
|
{
|
||||||
|
|
||||||
zSPtr->signExp = packToExtF80UI64( aPtr->sign, 0x7FFF );
|
zSPtr->signExp = defaultNaNExtF80UI64;
|
||||||
zSPtr->signif = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1;
|
zSPtr->signif = defaultNaNExtF80UI0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,9 +34,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "primitives.h"
|
#include "primitiveTypes.h"
|
||||||
|
|
||||||
|
#define softfloat_commonNaNToExtF80UI softfloat_commonNaNToExtF80UI
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -48,8 +49,8 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr )
|
|||||||
{
|
{
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
|
|
||||||
uiZ.v64 = (uint_fast16_t) aPtr->sign<<15 | 0x7FFF;
|
uiZ.v64 = defaultNaNExtF80UI64;
|
||||||
uiZ.v0 = UINT64_C( 0xC000000000000000 ) | aPtr->v64>>1;
|
uiZ.v0 = defaultNaNExtF80UI0;
|
||||||
return uiZ;
|
return uiZ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -36,7 +36,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "primitives.h"
|
#include "primitiveTypes.h"
|
||||||
|
|
||||||
|
#define softfloat_commonNaNToF128M softfloat_commonNaNToF128M
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -49,8 +51,10 @@ void
|
|||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr )
|
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr )
|
||||||
{
|
{
|
||||||
|
|
||||||
softfloat_shortShiftRight128M( (const uint32_t *) &aPtr->v0, 16, zWPtr );
|
zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;
|
||||||
zWPtr[indexWordHi( 4 )] |= (uint32_t) aPtr->sign<<31 | 0x7FFF8000;
|
zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;
|
||||||
|
zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
|
||||||
|
zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,9 +34,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "primitives.h"
|
#include "primitiveTypes.h"
|
||||||
|
|
||||||
|
#define softfloat_commonNaNToF128UI softfloat_commonNaNToF128UI
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -47,8 +48,8 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )
|
|||||||
{
|
{
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
|
|
||||||
uiZ = softfloat_shortShiftRight128( aPtr->v64, aPtr->v0, 16 );
|
uiZ.v64 = defaultNaNF128UI64;
|
||||||
uiZ.v64 |= (uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FFF800000000000 );
|
uiZ.v0 = defaultNaNF128UI0;
|
||||||
return uiZ;
|
return uiZ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
|
||||||
California. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by `aPtr' into a 16-bit floating-point
|
| This file intentionally contains no code.
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
return (uint_fast16_t) aPtr->sign<<15 | 0x7E00 | aPtr->v64>>54;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,51 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point
|
| This file intentionally contains no code.
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
return (uint_fast32_t) aPtr->sign<<31 | 0x7FC00000 | aPtr->v64>>41;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,53 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point
|
| This file intentionally contains no code.
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
return
|
|
||||||
(uint_fast64_t) aPtr->sign<<63 | UINT64_C( 0x7FF8000000000000 )
|
|
||||||
| aPtr->v64>>12;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,62 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "internals.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the 80-bit extended floating-point value pointed to by `aSPtr' is
|
| This file intentionally contains no code.
|
||||||
| a NaN, converts this NaN to the common NaN form, and stores the resulting
|
|
||||||
| common NaN at the location pointed to by `zPtr'. If the NaN is a signaling
|
|
||||||
| NaN, the invalid exception is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
|
||||||
softfloat_extF80MToCommonNaN(
|
|
||||||
const struct extFloat80M *aSPtr, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = signExtF80UI64( aSPtr->signExp );
|
|
||||||
zPtr->v64 = aSPtr->signif<<1;
|
|
||||||
zPtr->v0 = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,62 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0'
|
| This file intentionally contains no code.
|
||||||
| has the bit pattern of an 80-bit extended floating-point NaN, converts
|
|
||||||
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
|
||||||
| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid
|
|
||||||
| exception is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
|
||||||
softfloat_extF80UIToCommonNaN(
|
|
||||||
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = uiA64>>15;
|
|
||||||
zPtr->v64 = uiA0<<1;
|
|
||||||
zPtr->v0 = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,62 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "primitives.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN,
|
| This file intentionally contains no code.
|
||||||
| converts this NaN to the common NaN form, and stores the resulting common
|
|
||||||
| NaN at the location pointed to by `zPtr'. If the NaN is a signaling NaN,
|
|
||||||
| the invalid exception is raised. Argument `aWPtr' points to an array of
|
|
||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
|
||||||
| to form a 128-bit floating-point value.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
|
||||||
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( f128M_isSignalingNaN( (const float128_t *) aWPtr ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = aWPtr[indexWordHi( 4 )]>>31;
|
|
||||||
softfloat_shortShiftLeft128M( aWPtr, 16, (uint32_t *) &zPtr->v0 );
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,65 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "primitives.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0'
|
| This file intentionally contains no code.
|
||||||
| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to
|
|
||||||
| the common NaN form, and stores the resulting common NaN at the location
|
|
||||||
| pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception
|
|
||||||
| is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
|
||||||
softfloat_f128UIToCommonNaN(
|
|
||||||
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
struct uint128 NaNSig;
|
|
||||||
|
|
||||||
if ( softfloat_isSigNaNF128UI( uiA64, uiA0 ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
NaNSig = softfloat_shortShiftLeft128( uiA64, uiA0, 16 );
|
|
||||||
zPtr->sign = uiA64>>63;
|
|
||||||
zPtr->v64 = NaNSig.v64;
|
|
||||||
zPtr->v0 = NaNSig.v0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,59 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
|
||||||
California. All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming `uiA' has the bit pattern of a 16-bit floating-point NaN, converts
|
| This file intentionally contains no code.
|
||||||
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
|
||||||
| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid
|
|
||||||
| exception is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( softfloat_isSigNaNF16UI( uiA ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = uiA>>15;
|
|
||||||
zPtr->v64 = (uint_fast64_t) uiA<<54;
|
|
||||||
zPtr->v0 = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,59 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts
|
| This file intentionally contains no code.
|
||||||
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
|
||||||
| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid
|
|
||||||
| exception is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( softfloat_isSigNaNF32UI( uiA ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = uiA>>31;
|
|
||||||
zPtr->v64 = (uint_fast64_t) uiA<<41;
|
|
||||||
zPtr->v0 = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,59 +1,5 @@
|
|||||||
|
|
||||||
/*============================================================================
|
|
||||||
|
|
||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
|
||||||
Package, Release 3e, by John R. Hauser.
|
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer.
|
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions, and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
3. Neither the name of the University nor the names of its contributors may
|
|
||||||
be used to endorse or promote products derived from this software without
|
|
||||||
specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
=============================================================================*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "platform.h"
|
|
||||||
#include "specialize.h"
|
|
||||||
#include "softfloat.h"
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| This file intentionally contains no code.
|
||||||
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
|
||||||
| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid
|
|
||||||
| exception is raised.
|
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr )
|
|
||||||
{
|
|
||||||
|
|
||||||
if ( softfloat_isSigNaNF64UI( uiA ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
|
||||||
}
|
|
||||||
zPtr->sign = uiA>>63;
|
|
||||||
zPtr->v64 = uiA<<12;
|
|
||||||
zPtr->v0 = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,10 +34,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
#include "primitiveTypes.h"
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
@@ -54,54 +53,22 @@ void
|
|||||||
struct extFloat80M *zSPtr
|
struct extFloat80M *zSPtr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
uint_fast16_t ui64;
|
||||||
const struct extFloat80M *sPtr;
|
uint_fast64_t ui0;
|
||||||
bool isSigNaNB;
|
|
||||||
uint_fast16_t uiB64;
|
|
||||||
uint64_t uiB0;
|
|
||||||
uint_fast16_t uiA64;
|
|
||||||
uint64_t uiA0;
|
|
||||||
uint_fast16_t uiMagA64, uiMagB64;
|
|
||||||
|
|
||||||
isSigNaNA = extF80M_isSignalingNaN( (const extFloat80_t *) aSPtr );
|
ui64 = aSPtr->signExp;
|
||||||
sPtr = aSPtr;
|
ui0 = aSPtr->signif;
|
||||||
if ( ! bSPtr ) {
|
if (
|
||||||
if ( isSigNaNA ) softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_isSigNaNExtF80UI( ui64, ui0 )
|
||||||
goto copy;
|
|| (bSPtr
|
||||||
}
|
&& (ui64 = bSPtr->signExp,
|
||||||
isSigNaNB = extF80M_isSignalingNaN( (const extFloat80_t *) bSPtr );
|
ui0 = bSPtr->signif,
|
||||||
if ( isSigNaNA | isSigNaNB ) {
|
softfloat_isSigNaNExtF80UI( ui64, ui0 )))
|
||||||
|
) {
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) {
|
|
||||||
uiB64 = bSPtr->signExp;
|
|
||||||
if ( isSigNaNB ) goto returnLargerUIMag;
|
|
||||||
uiB0 = bSPtr->signif;
|
|
||||||
if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto copyB;
|
|
||||||
goto copy;
|
|
||||||
} else {
|
|
||||||
uiA64 = aSPtr->signExp;
|
|
||||||
uiA0 = aSPtr->signif;
|
|
||||||
if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto copy;
|
|
||||||
goto copyB;
|
|
||||||
}
|
}
|
||||||
}
|
zSPtr->signExp = defaultNaNExtF80UI64;
|
||||||
uiB64 = bSPtr->signExp;
|
zSPtr->signif = defaultNaNExtF80UI0;
|
||||||
returnLargerUIMag:
|
|
||||||
uiA64 = aSPtr->signExp;
|
|
||||||
uiMagA64 = uiA64 & 0x7FFF;
|
|
||||||
uiMagB64 = uiB64 & 0x7FFF;
|
|
||||||
if ( uiMagA64 < uiMagB64 ) goto copyB;
|
|
||||||
if ( uiMagB64 < uiMagA64 ) goto copy;
|
|
||||||
uiA0 = aSPtr->signif;
|
|
||||||
uiB0 = bSPtr->signif;
|
|
||||||
if ( uiA0 < uiB0 ) goto copyB;
|
|
||||||
if ( uiB0 < uiA0 ) goto copy;
|
|
||||||
if ( uiA64 < uiB64 ) goto copy;
|
|
||||||
copyB:
|
|
||||||
sPtr = bSPtr;
|
|
||||||
copy:
|
|
||||||
zSPtr->signExp = sPtr->signExp;
|
|
||||||
zSPtr->signif = sPtr->signif | UINT64_C( 0xC000000000000000 );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014, 2018 The Regents of the University of
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
California. All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -34,17 +34,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
#include "primitiveTypes.h"
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting the unsigned integer formed from concatenating 'uiA64' and
|
| Interpreting the unsigned integer formed from concatenating `uiA64' and
|
||||||
| 'uiA0' as an 80-bit extended floating-point value, and likewise interpreting
|
| `uiA0' as an 80-bit extended floating-point value, and likewise interpreting
|
||||||
| the unsigned integer formed from concatenating 'uiB64' and 'uiB0' as another
|
| the unsigned integer formed from concatenating `uiB64' and `uiB0' as another
|
||||||
| 80-bit extended floating-point value, and assuming at least on of these
|
| 80-bit extended floating-point value, and assuming at least on of these
|
||||||
| floating-point values is a NaN, returns the bit pattern of the combined NaN
|
| floating-point values is a NaN, returns the bit pattern of the combined NaN
|
||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
@@ -58,48 +57,16 @@ struct uint128
|
|||||||
uint_fast64_t uiB0
|
uint_fast64_t uiB0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool isSigNaNA, isSigNaNB;
|
|
||||||
uint_fast64_t uiNonsigA0, uiNonsigB0;
|
|
||||||
uint_fast16_t uiMagA64, uiMagB64;
|
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
if (
|
||||||
*------------------------------------------------------------------------*/
|
softfloat_isSigNaNExtF80UI( uiA64, uiA0 )
|
||||||
isSigNaNA = softfloat_isSigNaNExtF80UI( uiA64, uiA0 );
|
|| softfloat_isSigNaNExtF80UI( uiB64, uiB0 )
|
||||||
isSigNaNB = softfloat_isSigNaNExtF80UI( uiB64, uiB0 );
|
) {
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
| Make NaNs non-signaling.
|
|
||||||
*------------------------------------------------------------------------*/
|
|
||||||
uiNonsigA0 = uiA0 | UINT64_C( 0xC000000000000000 );
|
|
||||||
uiNonsigB0 = uiB0 | UINT64_C( 0xC000000000000000 );
|
|
||||||
/*------------------------------------------------------------------------
|
|
||||||
*------------------------------------------------------------------------*/
|
|
||||||
if ( isSigNaNA | isSigNaNB ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) {
|
|
||||||
if ( isSigNaNB ) goto returnLargerMag;
|
|
||||||
if ( isNaNExtF80UI( uiB64, uiB0 ) ) goto returnB;
|
|
||||||
goto returnA;
|
|
||||||
} else {
|
|
||||||
if ( isNaNExtF80UI( uiA64, uiA0 ) ) goto returnA;
|
|
||||||
goto returnB;
|
|
||||||
}
|
}
|
||||||
}
|
uiZ.v64 = defaultNaNExtF80UI64;
|
||||||
returnLargerMag:
|
uiZ.v0 = defaultNaNExtF80UI0;
|
||||||
uiMagA64 = uiA64 & 0x7FFF;
|
|
||||||
uiMagB64 = uiB64 & 0x7FFF;
|
|
||||||
if ( uiMagA64 < uiMagB64 ) goto returnB;
|
|
||||||
if ( uiMagB64 < uiMagA64 ) goto returnA;
|
|
||||||
if ( uiA0 < uiB0 ) goto returnB;
|
|
||||||
if ( uiB0 < uiA0 ) goto returnA;
|
|
||||||
if ( uiA64 < uiB64 ) goto returnA;
|
|
||||||
returnB:
|
|
||||||
uiZ.v64 = uiB64;
|
|
||||||
uiZ.v0 = uiNonsigB0;
|
|
||||||
return uiZ;
|
|
||||||
returnA:
|
|
||||||
uiZ.v64 = uiA64;
|
|
||||||
uiZ.v0 = uiNonsigA0;
|
|
||||||
return uiZ;
|
return uiZ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015, 2018 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,43 +34,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
#include "primitiveTypes.h"
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
||||||
| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location
|
| 'aWPtr' and 'bWPtr' is a NaN, stores the combined NaN result at the location
|
||||||
| pointed to by `zWPtr'. If either original floating-point value is a
|
| pointed to by 'zWPtr'. If either original floating-point value is a
|
||||||
| signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr',
|
| signaling NaN, the invalid exception is raised. Each of 'aWPtr', 'bWPtr',
|
||||||
| and `zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
softfloat_propagateNaNF128M(
|
softfloat_propagateNaNF128M(
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr )
|
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr )
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
|
||||||
const uint32_t *ptr;
|
|
||||||
|
|
||||||
ptr = aWPtr;
|
|
||||||
isSigNaNA = f128M_isSignalingNaN( (const float128_t *) aWPtr );
|
|
||||||
if (
|
if (
|
||||||
isSigNaNA
|
f128M_isSignalingNaN( (const float128_t *) aWPtr )
|
||||||
|| (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr ))
|
|| (bWPtr && f128M_isSignalingNaN( (const float128_t *) bWPtr ))
|
||||||
) {
|
) {
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) goto copy;
|
|
||||||
}
|
}
|
||||||
if ( ! softfloat_isNaNF128M( aWPtr ) ) ptr = bWPtr;
|
zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;
|
||||||
copy:
|
zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;
|
||||||
zWPtr[indexWordHi( 4 )] = ptr[indexWordHi( 4 )] | 0x00008000;
|
zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
|
||||||
zWPtr[indexWord( 4, 2 )] = ptr[indexWord( 4, 2 )];
|
zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;
|
||||||
zWPtr[indexWord( 4, 1 )] = ptr[indexWord( 4, 1 )];
|
|
||||||
zWPtr[indexWord( 4, 0 )] = ptr[indexWord( 4, 0 )];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,10 +34,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
#include "primitiveTypes.h"
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
@@ -58,23 +57,16 @@ struct uint128
|
|||||||
uint_fast64_t uiB0
|
uint_fast64_t uiB0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
|
||||||
struct uint128 uiZ;
|
struct uint128 uiZ;
|
||||||
|
|
||||||
isSigNaNA = softfloat_isSigNaNF128UI( uiA64, uiA0 );
|
if (
|
||||||
if ( isSigNaNA || softfloat_isSigNaNF128UI( uiB64, uiB0 ) ) {
|
softfloat_isSigNaNF128UI( uiA64, uiA0 )
|
||||||
|
|| softfloat_isSigNaNF128UI( uiB64, uiB0 )
|
||||||
|
) {
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) goto returnNonsigA;
|
|
||||||
}
|
}
|
||||||
if ( isNaNF128UI( uiA64, uiA0 ) ) {
|
uiZ.v64 = defaultNaNF128UI64;
|
||||||
returnNonsigA:
|
uiZ.v0 = defaultNaNF128UI0;
|
||||||
uiZ.v64 = uiA64;
|
|
||||||
uiZ.v0 = uiA0;
|
|
||||||
} else {
|
|
||||||
uiZ.v64 = uiB64;
|
|
||||||
uiZ.v0 = uiB0;
|
|
||||||
}
|
|
||||||
uiZ.v64 |= UINT64_C( 0x0000800000000000 );
|
|
||||||
return uiZ;
|
return uiZ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
|
||||||
California. All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
@@ -34,10 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
@@ -50,14 +48,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
uint_fast16_t
|
uint_fast16_t
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB )
|
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB )
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
|
||||||
|
|
||||||
isSigNaNA = softfloat_isSigNaNF16UI( uiA );
|
if ( softfloat_isSigNaNF16UI( uiA ) || softfloat_isSigNaNF16UI( uiB ) ) {
|
||||||
if ( isSigNaNA || softfloat_isSigNaNF16UI( uiB ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) return uiA | 0x0200;
|
|
||||||
}
|
}
|
||||||
return (isNaNF16UI( uiA ) ? uiA : uiB) | 0x0200;
|
return defaultNaNF16UI;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,10 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
@@ -50,14 +48,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
uint_fast32_t
|
uint_fast32_t
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB )
|
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB )
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
|
||||||
|
|
||||||
isSigNaNA = softfloat_isSigNaNF32UI( uiA );
|
if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) {
|
||||||
if ( isSigNaNA || softfloat_isSigNaNF32UI( uiB ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) return uiA | 0x00400000;
|
|
||||||
}
|
}
|
||||||
return (isNaNF32UI( uiA ) ? uiA : uiB) | 0x00400000;
|
return defaultNaNF32UI;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
Package, Release 3e, by John R. Hauser.
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
Copyright 2011, 2012, 2013, 2014 The Regents of the University of California.
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
All rights reserved.
|
California. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
@@ -34,10 +34,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "internals.h"
|
|
||||||
#include "specialize.h"
|
#include "specialize.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
|
||||||
@@ -50,14 +48,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
uint_fast64_t
|
uint_fast64_t
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB )
|
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB )
|
||||||
{
|
{
|
||||||
bool isSigNaNA;
|
|
||||||
|
|
||||||
isSigNaNA = softfloat_isSigNaNF64UI( uiA );
|
if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) {
|
||||||
if ( isSigNaNA || softfloat_isSigNaNF64UI( uiB ) ) {
|
|
||||||
softfloat_raiseFlags( softfloat_flag_invalid );
|
softfloat_raiseFlags( softfloat_flag_invalid );
|
||||||
if ( isSigNaNA ) return uiA | UINT64_C( 0x0008000000000000 );
|
|
||||||
}
|
}
|
||||||
return (isNaNF64UI( uiA ) ? uiA : uiB) | UINT64_C( 0x0008000000000000 );
|
return defaultNaNF64UI;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef specialize_h
|
#ifndef specialize_h
|
||||||
#define specialize_h 1
|
#define specialize_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
#include "softfloat.h"
|
#include "softfloat.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Default value for 'softfloat_detectTininess'.
|
| Default value for 'softfloat_detectTininess'.
|
||||||
@@ -51,19 +51,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| The values to return on conversions to 32-bit integer formats that raise an
|
| The values to return on conversions to 32-bit integer formats that raise an
|
||||||
| invalid exception.
|
| invalid exception.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define ui32_fromPosOverflow UINT32_C(0xFFFFFFFF)
|
#define ui32_fromPosOverflow 0xFFFFFFFF
|
||||||
#define ui32_fromNegOverflow UINT32_C(0x0)
|
#define ui32_fromNegOverflow 0
|
||||||
#define ui32_fromNaN UINT32_C(0xFFFFFFFF)
|
#define ui32_fromNaN 0xFFFFFFFF
|
||||||
#define i32_fromPosOverflow INT64_C(0x7FFFFFFF)
|
#define i32_fromPosOverflow 0x7FFFFFFF
|
||||||
#define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF)-1)
|
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
|
||||||
#define i32_fromNaN INT64_C(0x7FFFFFFF)
|
#define i32_fromNaN 0x7FFFFFFF
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The values to return on conversions to 64-bit integer formats that raise an
|
| The values to return on conversions to 64-bit integer formats that raise an
|
||||||
| invalid exception.
|
| invalid exception.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
|
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
|
||||||
#define ui64_fromNegOverflow UINT64_C( 0x0 )
|
#define ui64_fromNegOverflow 0
|
||||||
#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
|
#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
|
||||||
#define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
|
#define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
|
||||||
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
|
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
|
||||||
@@ -74,18 +74,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| to another.
|
| to another.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct commonNaN {
|
struct commonNaN {
|
||||||
bool sign;
|
char _unused;
|
||||||
#ifdef LITTLEENDIAN
|
|
||||||
uint64_t v0, v64;
|
|
||||||
#else
|
|
||||||
uint64_t v64, v0;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 16-bit floating-point NaN.
|
| The bit pattern for a default generated 16-bit floating-point NaN.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define defaultNaNF16UI 0xFE00
|
#define defaultNaNF16UI 0x7E00
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a
|
| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a
|
||||||
@@ -94,19 +89,38 @@ struct commonNaN {
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
|
#define softfloat_isSigNaNF16UI(uiA) ((((uiA)&0x7E00) == 0x7C00) && ((uiA)&0x01FF))
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Returns true when 16-bit unsigned integer 'uiA' has the bit pattern of a
|
||||||
|
| 16-bit brain floating-point (BF16) signaling NaN.
|
||||||
|
| Note: This macro evaluates its argument more than once.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define softfloat_isSigNaNBF16UI(uiA) ((((uiA)&0x7FC0) == 0x7F80) && ((uiA)&0x003F))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 16-bit floating-point NaN, converts
|
||||||
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f16UIToCommonNaN( uint_fast16_t uiA, struct commonNaN *zPtr );
|
#define softfloat_f16UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&0x0200)) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Assuming 'uiA' has the bit pattern of a 16-bit BF16 floating-point NaN, converts
|
||||||
|
| this NaN to the common NaN form, and stores the resulting common NaN at the
|
||||||
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
|
| exception is raised.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define softfloat_bf16UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&0x0040)) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
|
#define softfloat_commonNaNToF16UI(aPtr) ((uint_fast16_t)defaultNaNF16UI)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
|
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 16-bit floating-
|
||||||
@@ -114,8 +128,18 @@ uint_fast16_t softfloat_commonNaNToF16UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast16_t
|
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
|
||||||
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| The bit pattern for a default generated 16-bit BF16 floating-point NaN.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define defaultNaNBF16UI 0x7FC0
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| Converts the common NaN pointed to by 'aPtr' into a 16-bit floating-point
|
||||||
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define softfloat_commonNaNToBF16UI(aPtr) ((uint_fast16_t)defaultNaNBF16UI)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 32-bit floating-point NaN.
|
| The bit pattern for a default generated 32-bit floating-point NaN.
|
||||||
@@ -135,13 +159,15 @@ uint_fast16_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f32UIToCommonNaN( uint_fast32_t uiA, struct commonNaN *zPtr );
|
#define softfloat_f32UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&0x00400000)) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 32-bit floating-point
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
|
#define softfloat_commonNaNToF32UI(aPtr) ((uint_fast32_t)defaultNaNF32UI)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
|
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 32-bit floating-
|
||||||
@@ -149,8 +175,7 @@ uint_fast32_t softfloat_commonNaNToF32UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t
|
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
|
||||||
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 64-bit floating-point NaN.
|
| The bit pattern for a default generated 64-bit floating-point NaN.
|
||||||
@@ -162,7 +187,8 @@ uint_fast32_t
|
|||||||
| 64-bit floating-point signaling NaN.
|
| 64-bit floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its argument more than once.
|
| Note: This macro evaluates its argument more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF )))
|
#define softfloat_isSigNaNF64UI(uiA) \
|
||||||
|
((((uiA)&UINT64_C(0x7FF8000000000000)) == UINT64_C(0x7FF0000000000000)) && ((uiA)&UINT64_C(0x0007FFFFFFFFFFFF)))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
| Assuming 'uiA' has the bit pattern of a 64-bit floating-point NaN, converts
|
||||||
@@ -170,13 +196,15 @@ uint_fast32_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void softfloat_f64UIToCommonNaN( uint_fast64_t uiA, struct commonNaN *zPtr );
|
#define softfloat_f64UIToCommonNaN(uiA, zPtr) \
|
||||||
|
if(!((uiA)&UINT64_C(0x0008000000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 64-bit floating-point
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
|
#define softfloat_commonNaNToF64UI(aPtr) ((uint_fast64_t)defaultNaNF64UI)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
|
| Interpreting 'uiA' and 'uiB' as the bit patterns of two 64-bit floating-
|
||||||
@@ -184,13 +212,12 @@ uint_fast64_t softfloat_commonNaNToF64UI( const struct commonNaN *aPtr );
|
|||||||
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
|
||||||
| signaling NaN, the invalid exception is raised.
|
| signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
|
||||||
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
| The bit pattern for a default generated 80-bit extended floating-point NaN.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define defaultNaNExtF80UI64 0xFFFF
|
#define defaultNaNExtF80UI64 0x7FFF
|
||||||
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
|
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -199,7 +226,8 @@ uint_fast64_t
|
|||||||
| floating-point signaling NaN.
|
| floating-point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF )))
|
#define softfloat_isSigNaNExtF80UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&0x7FFF) == 0x7FFF) && !((uiA0)&UINT64_C(0x4000000000000000)) && ((uiA0)&UINT64_C(0x3FFFFFFFFFFFFFFF)))
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
@@ -215,16 +243,26 @@ uint_fast64_t
|
|||||||
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#define softfloat_extF80UIToCommonNaN(uiA64, uiA0, zPtr) \
|
||||||
softfloat_extF80UIToCommonNaN(
|
if(!((uiA0)&UINT64_C(0x4000000000000000))) \
|
||||||
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
| floating-point NaN, and returns the bit pattern of this value as an unsigned
|
| floating-point NaN, and returns the bit pattern of this value as an unsigned
|
||||||
| integer.
|
| integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
#if defined INLINE && !defined softfloat_commonNaNToExtF80UI
|
||||||
|
INLINE
|
||||||
|
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr) {
|
||||||
|
struct uint128 uiZ;
|
||||||
|
uiZ.v64 = defaultNaNExtF80UI64;
|
||||||
|
uiZ.v0 = defaultNaNExtF80UI0;
|
||||||
|
return uiZ;
|
||||||
|
}
|
||||||
|
#else
|
||||||
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
|
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting the unsigned integer formed from concatenating 'uiA64' and
|
| Interpreting the unsigned integer formed from concatenating 'uiA64' and
|
||||||
@@ -235,18 +273,12 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
|
|||||||
| result. If either original floating-point value is a signaling NaN, the
|
| result. If either original floating-point value is a signaling NaN, the
|
||||||
| invalid exception is raised.
|
| invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNExtF80UI(uint_fast16_t uiA64, uint_fast64_t uiA0, uint_fast16_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNExtF80UI(
|
|
||||||
uint_fast16_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast16_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 )
|
#define defaultNaNF128UI64 UINT64_C(0x7FFF800000000000)
|
||||||
#define defaultNaNF128UI0 UINT64_C(0)
|
#define defaultNaNF128UI0 UINT64_C(0)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -255,7 +287,8 @@ struct uint128
|
|||||||
| point signaling NaN.
|
| point signaling NaN.
|
||||||
| Note: This macro evaluates its arguments more than once.
|
| Note: This macro evaluates its arguments more than once.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF ))))
|
#define softfloat_isSigNaNF128UI(uiA64, uiA0) \
|
||||||
|
((((uiA64)&UINT64_C(0x7FFF800000000000)) == UINT64_C(0x7FFF000000000000)) && ((uiA0) || ((uiA64)&UINT64_C(0x00007FFFFFFFFFFF))))
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
| Assuming the unsigned integer formed from concatenating 'uiA64' and 'uiA0'
|
||||||
@@ -264,15 +297,25 @@ struct uint128
|
|||||||
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
|
||||||
| is raised.
|
| is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#define softfloat_f128UIToCommonNaN(uiA64, uiA0, zPtr) \
|
||||||
softfloat_f128UIToCommonNaN(
|
if(!((uiA64)&UINT64_C(0x0000800000000000))) \
|
||||||
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
| NaN, and returns the bit pattern of this value as an unsigned integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
#if defined INLINE && !defined softfloat_commonNaNToF128UI
|
||||||
|
INLINE
|
||||||
|
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN* aPtr) {
|
||||||
|
struct uint128 uiZ;
|
||||||
|
uiZ.v64 = defaultNaNF128UI64;
|
||||||
|
uiZ.v0 = defaultNaNF128UI0;
|
||||||
|
return uiZ;
|
||||||
|
}
|
||||||
|
#else
|
||||||
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
|
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Interpreting the unsigned integer formed from concatenating 'uiA64' and
|
| Interpreting the unsigned integer formed from concatenating 'uiA64' and
|
||||||
@@ -283,13 +326,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
|
|||||||
| If either original floating-point value is a signaling NaN, the invalid
|
| If either original floating-point value is a signaling NaN, the invalid
|
||||||
| exception is raised.
|
| exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
|
||||||
softfloat_propagateNaNF128UI(
|
|
||||||
uint_fast64_t uiA64,
|
|
||||||
uint_fast64_t uiA0,
|
|
||||||
uint_fast64_t uiB64,
|
|
||||||
uint_fast64_t uiB0
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -304,18 +341,24 @@ struct uint128
|
|||||||
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
|
||||||
| NaN, the invalid exception is raised.
|
| NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#define softfloat_extF80MToCommonNaN(aSPtr, zPtr) \
|
||||||
softfloat_extF80MToCommonNaN(
|
if(!((aSPtr)->signif & UINT64_C(0x4000000000000000))) \
|
||||||
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
| Converts the common NaN pointed to by 'aPtr' into an 80-bit extended
|
||||||
| floating-point NaN, and stores this NaN at the location pointed to by
|
| floating-point NaN, and stores this NaN at the location pointed to by
|
||||||
| 'zSPtr'.
|
| 'zSPtr'.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#if defined INLINE && !defined softfloat_commonNaNToExtF80M
|
||||||
softfloat_commonNaNToExtF80M(
|
INLINE
|
||||||
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr) {
|
||||||
|
zSPtr->signExp = defaultNaNExtF80UI64;
|
||||||
|
zSPtr->signif = defaultNaNExtF80UI0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 80-bit extended floating-point values
|
| Assuming at least one of the two 80-bit extended floating-point values
|
||||||
@@ -323,17 +366,12 @@ void
|
|||||||
| at the location pointed to by 'zSPtr'. If either original floating-point
|
| at the location pointed to by 'zSPtr'. If either original floating-point
|
||||||
| value is a signaling NaN, the invalid exception is raised.
|
| value is a signaling NaN, the invalid exception is raised.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNExtF80M(const struct extFloat80M* aSPtr, const struct extFloat80M* bSPtr, struct extFloat80M* zSPtr);
|
||||||
softfloat_propagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *aSPtr,
|
|
||||||
const struct extFloat80M *bSPtr,
|
|
||||||
struct extFloat80M *zSPtr
|
|
||||||
);
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The bit pattern for a default generated 128-bit floating-point NaN.
|
| The bit pattern for a default generated 128-bit floating-point NaN.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#define defaultNaNF128UI96 0xFFFF8000
|
#define defaultNaNF128UI96 0x7FFF8000
|
||||||
#define defaultNaNF128UI64 0
|
#define defaultNaNF128UI64 0
|
||||||
#define defaultNaNF128UI32 0
|
#define defaultNaNF128UI32 0
|
||||||
#define defaultNaNF128UI0 0
|
#define defaultNaNF128UI0 0
|
||||||
@@ -346,8 +384,9 @@ void
|
|||||||
| four 32-bit elements that concatenate in the platform's normal endian order
|
| four 32-bit elements that concatenate in the platform's normal endian order
|
||||||
| to form a 128-bit floating-point value.
|
| to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#define softfloat_f128MToCommonNaN(aWPtr, zPtr) \
|
||||||
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
|
if(!((aWPtr)[indexWordHi(4)] & UINT64_C(0x0000800000000000))) \
|
||||||
|
softfloat_raiseFlags(softfloat_flag_invalid)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
| Converts the common NaN pointed to by 'aPtr' into a 128-bit floating-point
|
||||||
@@ -355,8 +394,17 @@ void
|
|||||||
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
| 'zWPtr' points to an array of four 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form a 128-bit floating-point value.
|
| platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
#if defined INLINE && !defined softfloat_commonNaNToF128M
|
||||||
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
|
INLINE
|
||||||
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr) {
|
||||||
|
zWPtr[indexWord(4, 3)] = defaultNaNF128UI96;
|
||||||
|
zWPtr[indexWord(4, 2)] = defaultNaNF128UI64;
|
||||||
|
zWPtr[indexWord(4, 1)] = defaultNaNF128UI32;
|
||||||
|
zWPtr[indexWord(4, 0)] = defaultNaNF128UI0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
| Assuming at least one of the two 128-bit floating-point values pointed to by
|
||||||
@@ -366,11 +414,8 @@ void
|
|||||||
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
| and 'zWPtr' points to an array of four 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form a 128-bit floating-point value.
|
| the platform's normal endian order to form a 128-bit floating-point value.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
|
||||||
softfloat_propagateNaNF128M(
|
|
||||||
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
|
California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "internals.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
|
bool bf16_isSignalingNaN( bfloat16_t a )
|
||||||
|
{
|
||||||
|
union ui16_bf16 uA;
|
||||||
|
|
||||||
|
uA.f = a;
|
||||||
|
return softfloat_isSigNaNBF16UI( uA.ui );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
|
California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "internals.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
|
float32_t bf16_to_f32( bfloat16_t a )
|
||||||
|
{
|
||||||
|
union ui16_bf16 uA;
|
||||||
|
uint_fast16_t uiA;
|
||||||
|
bool sign;
|
||||||
|
int_fast16_t exp;
|
||||||
|
uint_fast16_t frac;
|
||||||
|
struct commonNaN commonNaN;
|
||||||
|
uint_fast32_t uiZ;
|
||||||
|
struct exp8_sig16 normExpSig;
|
||||||
|
union ui32_f32 uZ;
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
uA.f = a;
|
||||||
|
uiA = uA.ui;
|
||||||
|
sign = signBF16UI( uiA );
|
||||||
|
exp = expBF16UI( uiA );
|
||||||
|
frac = fracBF16UI( uiA );
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
// NaN or Inf
|
||||||
|
if ( exp == 0xFF ) {
|
||||||
|
if ( frac ) {
|
||||||
|
softfloat_bf16UIToCommonNaN( uiA, &commonNaN );
|
||||||
|
uiZ = softfloat_commonNaNToF32UI( &commonNaN );
|
||||||
|
} else {
|
||||||
|
uiZ = packToF32UI( sign, 0xFF, 0 );
|
||||||
|
}
|
||||||
|
goto uiZ;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
// packToF32UI simply packs bitfields without any numerical change
|
||||||
|
// which means it can be used directly for any BF16 to f32 conversions which
|
||||||
|
// does not require bits manipulation
|
||||||
|
// (that is everything where the 16-bit are just padded right with 16 zeros, including
|
||||||
|
// subnormal numbers)
|
||||||
|
uiZ = packToF32UI( sign, exp, ((uint_fast32_t) frac) <<16 );
|
||||||
|
uiZ:
|
||||||
|
uZ.ui = uiZ;
|
||||||
|
return uZ.f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of
|
||||||
|
California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "internals.h"
|
||||||
|
#include "specialize.h"
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
bfloat16_t f32_to_bf16( float32_t a )
|
||||||
|
{
|
||||||
|
union ui32_f32 uA;
|
||||||
|
uint_fast32_t uiA;
|
||||||
|
bool sign;
|
||||||
|
int_fast16_t exp;
|
||||||
|
uint_fast32_t frac;
|
||||||
|
struct commonNaN commonNaN;
|
||||||
|
uint_fast16_t uiZ, frac16;
|
||||||
|
union ui16_bf16 uZ;
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
uA.f = a;
|
||||||
|
uiA = uA.ui;
|
||||||
|
sign = signF32UI( uiA );
|
||||||
|
exp = expF32UI( uiA );
|
||||||
|
frac = fracF32UI( uiA );
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
// infinity or NaN cases
|
||||||
|
if ( exp == 0xFF ) {
|
||||||
|
if ( frac ) {
|
||||||
|
// NaN case
|
||||||
|
softfloat_f32UIToCommonNaN( uiA, &commonNaN );
|
||||||
|
uiZ = softfloat_commonNaNToBF16UI( &commonNaN );
|
||||||
|
} else {
|
||||||
|
// infinity case
|
||||||
|
uiZ = packToBF16UI( sign, 0xFF, 0 );
|
||||||
|
}
|
||||||
|
goto uiZ;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
// frac is a 24-bit mantissa, right shifted by 9
|
||||||
|
// In the normal case, (24-9) = 15 are set
|
||||||
|
frac16 = frac>>9 | ((frac & 0x1FF) != 0);
|
||||||
|
if ( ! (exp | frac16) ) {
|
||||||
|
uiZ = packToBF16UI( sign, 0, 0 );
|
||||||
|
goto uiZ;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
// softfloat_roundPackToBF16 exponent argument (2nd argument)
|
||||||
|
// must correspond to the exponent of fracIn[13] bits
|
||||||
|
// (fracIn is the 3rd and last argument)
|
||||||
|
uint_fast32_t mask = exp ? 0x4000 : 0x0; // implicit one mask added if input is a normal number
|
||||||
|
// exponent for the lowest normal and largest subnormal should be equal
|
||||||
|
// but is not in IEEE encoding so mantissa must be partially normalized
|
||||||
|
// (by one bit) for subnormal numbers. Such that (exp - 1) corresponds
|
||||||
|
// to the exponent of frac16[13]
|
||||||
|
frac16 = frac16 << (exp ? 0 : 1);
|
||||||
|
return softfloat_roundPackToBF16( sign, exp - 1, frac16 | mask );
|
||||||
|
uiZ:
|
||||||
|
uZ.ui = uiZ;
|
||||||
|
return uZ.f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -72,6 +72,9 @@ float16_t f32_to_f16( float32_t a )
|
|||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
*------------------------------------------------------------------------*/
|
*------------------------------------------------------------------------*/
|
||||||
|
// frac is a 24-bit significand, the bottom 9 bits LSB are extracted and OR-red
|
||||||
|
// into a sticky flag, the top 15 MSBs are extracted, the LSB of this top slice
|
||||||
|
// is OR-red with the sticky
|
||||||
frac16 = frac>>9 | ((frac & 0x1FF) != 0);
|
frac16 = frac>>9 | ((frac & 0x1FF) != 0);
|
||||||
if ( ! (exp | frac16) ) {
|
if ( ! (exp | frac16) ) {
|
||||||
uiZ = packToF16UI( sign, 0, 0 );
|
uiZ = packToF16UI( sign, 0, 0 );
|
||||||
|
|||||||
@@ -37,33 +37,47 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef internals_h
|
#ifndef internals_h
|
||||||
#define internals_h 1
|
#define internals_h 1
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitives.h"
|
#include "primitives.h"
|
||||||
#include "softfloat_types.h"
|
#include "softfloat_types.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
union ui16_f16 { uint16_t ui; float16_t f; };
|
union ui16_f16 {
|
||||||
union ui32_f32 { uint32_t ui; float32_t f; };
|
uint16_t ui;
|
||||||
union ui64_f64 { uint64_t ui; float64_t f; };
|
float16_t f;
|
||||||
|
};
|
||||||
|
union ui16_bf16 {
|
||||||
|
uint16_t ui;
|
||||||
|
bfloat16_t f;
|
||||||
|
};
|
||||||
|
union ui32_f32 {
|
||||||
|
uint32_t ui;
|
||||||
|
float32_t f;
|
||||||
|
};
|
||||||
|
union ui64_f64 {
|
||||||
|
uint64_t ui;
|
||||||
|
float64_t f;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
union extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; };
|
union extF80M_extF80 {
|
||||||
union ui128_f128 { struct uint128 ui; float128_t f; };
|
struct extFloat80M fM;
|
||||||
|
extFloat80_t f;
|
||||||
|
};
|
||||||
|
union ui128_f128 {
|
||||||
|
struct uint128 ui;
|
||||||
|
float128_t f;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
enum { softfloat_mulAdd_subC = 1, softfloat_mulAdd_subProd = 2 };
|
||||||
softfloat_mulAdd_subC = 1,
|
|
||||||
softfloat_mulAdd_subProd = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast32_t softfloat_roundToUI32(bool, uint_fast64_t, uint_fast8_t, bool);
|
uint_fast32_t softfloat_roundToUI32(bool, uint_fast64_t, uint_fast8_t, bool);
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
uint_fast64_t
|
uint_fast64_t softfloat_roundToUI64(bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool);
|
||||||
softfloat_roundToUI64(
|
|
||||||
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );
|
|
||||||
#else
|
#else
|
||||||
uint_fast64_t softfloat_roundMToUI64(bool, uint32_t*, uint_fast8_t, bool);
|
uint_fast64_t softfloat_roundMToUI64(bool, uint32_t*, uint_fast8_t, bool);
|
||||||
#endif
|
#endif
|
||||||
@@ -71,9 +85,7 @@ uint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool );
|
|||||||
int_fast32_t softfloat_roundToI32(bool, uint_fast64_t, uint_fast8_t, bool);
|
int_fast32_t softfloat_roundToI32(bool, uint_fast64_t, uint_fast8_t, bool);
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
int_fast64_t
|
int_fast64_t softfloat_roundToI64(bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool);
|
||||||
softfloat_roundToI64(
|
|
||||||
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );
|
|
||||||
#else
|
#else
|
||||||
int_fast64_t softfloat_roundMToI64(bool, uint32_t*, uint_fast8_t, bool);
|
int_fast64_t softfloat_roundMToI64(bool, uint32_t*, uint_fast8_t, bool);
|
||||||
#endif
|
#endif
|
||||||
@@ -87,7 +99,10 @@ int_fast64_t softfloat_roundMToI64( bool, uint32_t *, uint_fast8_t, bool );
|
|||||||
|
|
||||||
#define isNaNF16UI(a) (((~(a)&0x7C00) == 0) && ((a)&0x03FF))
|
#define isNaNF16UI(a) (((~(a)&0x7C00) == 0) && ((a)&0x03FF))
|
||||||
|
|
||||||
struct exp8_sig16 { int_fast8_t exp; uint_fast16_t sig; };
|
struct exp8_sig16 {
|
||||||
|
int_fast8_t exp;
|
||||||
|
uint_fast16_t sig;
|
||||||
|
};
|
||||||
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t);
|
struct exp8_sig16 softfloat_normSubnormalF16Sig(uint_fast16_t);
|
||||||
|
|
||||||
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t);
|
float16_t softfloat_roundPackToF16(bool, int_fast16_t, uint_fast16_t);
|
||||||
@@ -95,9 +110,19 @@ float16_t softfloat_normRoundPackToF16( bool, int_fast16_t, uint_fast16_t );
|
|||||||
|
|
||||||
float16_t softfloat_addMagsF16(uint_fast16_t, uint_fast16_t);
|
float16_t softfloat_addMagsF16(uint_fast16_t, uint_fast16_t);
|
||||||
float16_t softfloat_subMagsF16(uint_fast16_t, uint_fast16_t);
|
float16_t softfloat_subMagsF16(uint_fast16_t, uint_fast16_t);
|
||||||
float16_t
|
float16_t softfloat_mulAddF16(uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t);
|
||||||
softfloat_mulAddF16(
|
|
||||||
uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t );
|
/*----------------------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
#define signBF16UI(a) ((bool)((uint16_t)(a) >> 15))
|
||||||
|
#define expBF16UI(a) ((int_fast16_t)((a) >> 7) & 0xFF)
|
||||||
|
#define fracBF16UI(a) ((a)&0x07F)
|
||||||
|
#define packToBF16UI(sign, exp, sig) (((uint16_t)(sign) << 15) + ((uint16_t)(exp) << 7) + (sig))
|
||||||
|
|
||||||
|
#define isNaNBF16UI(a) (((~(a)&0x7FC0) == 0) && ((a)&0x07F))
|
||||||
|
|
||||||
|
bfloat16_t softfloat_roundPackToBF16(bool, int_fast16_t, uint_fast16_t);
|
||||||
|
struct exp8_sig16 softfloat_normSubnormalBF16Sig(uint_fast16_t);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -108,7 +133,10 @@ float16_t
|
|||||||
|
|
||||||
#define isNaNF32UI(a) (((~(a)&0x7F800000) == 0) && ((a)&0x007FFFFF))
|
#define isNaNF32UI(a) (((~(a)&0x7F800000) == 0) && ((a)&0x007FFFFF))
|
||||||
|
|
||||||
struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; };
|
struct exp16_sig32 {
|
||||||
|
int_fast16_t exp;
|
||||||
|
uint_fast32_t sig;
|
||||||
|
};
|
||||||
struct exp16_sig32 softfloat_normSubnormalF32Sig(uint_fast32_t);
|
struct exp16_sig32 softfloat_normSubnormalF32Sig(uint_fast32_t);
|
||||||
|
|
||||||
float32_t softfloat_roundPackToF32(bool, int_fast16_t, uint_fast32_t);
|
float32_t softfloat_roundPackToF32(bool, int_fast16_t, uint_fast32_t);
|
||||||
@@ -116,9 +144,7 @@ float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t );
|
|||||||
|
|
||||||
float32_t softfloat_addMagsF32(uint_fast32_t, uint_fast32_t);
|
float32_t softfloat_addMagsF32(uint_fast32_t, uint_fast32_t);
|
||||||
float32_t softfloat_subMagsF32(uint_fast32_t, uint_fast32_t);
|
float32_t softfloat_subMagsF32(uint_fast32_t, uint_fast32_t);
|
||||||
float32_t
|
float32_t softfloat_mulAddF32(uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t);
|
||||||
softfloat_mulAddF32(
|
|
||||||
uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -129,7 +155,10 @@ float32_t
|
|||||||
|
|
||||||
#define isNaNF64UI(a) (((~(a)&UINT64_C(0x7FF0000000000000)) == 0) && ((a)&UINT64_C(0x000FFFFFFFFFFFFF)))
|
#define isNaNF64UI(a) (((~(a)&UINT64_C(0x7FF0000000000000)) == 0) && ((a)&UINT64_C(0x000FFFFFFFFFFFFF)))
|
||||||
|
|
||||||
struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; };
|
struct exp16_sig64 {
|
||||||
|
int_fast16_t exp;
|
||||||
|
uint_fast64_t sig;
|
||||||
|
};
|
||||||
struct exp16_sig64 softfloat_normSubnormalF64Sig(uint_fast64_t);
|
struct exp16_sig64 softfloat_normSubnormalF64Sig(uint_fast64_t);
|
||||||
|
|
||||||
float64_t softfloat_roundPackToF64(bool, int_fast16_t, uint_fast64_t);
|
float64_t softfloat_roundPackToF64(bool, int_fast16_t, uint_fast64_t);
|
||||||
@@ -137,9 +166,7 @@ float64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t );
|
|||||||
|
|
||||||
float64_t softfloat_addMagsF64(uint_fast64_t, uint_fast64_t, bool);
|
float64_t softfloat_addMagsF64(uint_fast64_t, uint_fast64_t, bool);
|
||||||
float64_t softfloat_subMagsF64(uint_fast64_t, uint_fast64_t, bool);
|
float64_t softfloat_subMagsF64(uint_fast64_t, uint_fast64_t, bool);
|
||||||
float64_t
|
float64_t softfloat_mulAddF64(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
|
||||||
softfloat_mulAddF64(
|
|
||||||
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -154,22 +181,17 @@ float64_t
|
|||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
struct exp32_sig64 { int_fast32_t exp; uint64_t sig; };
|
struct exp32_sig64 {
|
||||||
|
int_fast32_t exp;
|
||||||
|
uint64_t sig;
|
||||||
|
};
|
||||||
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t);
|
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t);
|
||||||
|
|
||||||
extFloat80_t
|
extFloat80_t softfloat_roundPackToExtF80(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
|
||||||
softfloat_roundPackToExtF80(
|
extFloat80_t softfloat_normRoundPackToExtF80(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
|
||||||
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
|
|
||||||
extFloat80_t
|
|
||||||
softfloat_normRoundPackToExtF80(
|
|
||||||
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
|
|
||||||
|
|
||||||
extFloat80_t
|
extFloat80_t softfloat_addMagsExtF80(uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool);
|
||||||
softfloat_addMagsExtF80(
|
extFloat80_t softfloat_subMagsExtF80(uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool);
|
||||||
uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );
|
|
||||||
extFloat80_t
|
|
||||||
softfloat_subMagsExtF80(
|
|
||||||
uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -180,67 +202,35 @@ extFloat80_t
|
|||||||
|
|
||||||
#define isNaNF128UI(a64, a0) (((~(a64)&UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64)&UINT64_C(0x0000FFFFFFFFFFFF))))
|
#define isNaNF128UI(a64, a0) (((~(a64)&UINT64_C(0x7FFF000000000000)) == 0) && (a0 || ((a64)&UINT64_C(0x0000FFFFFFFFFFFF))))
|
||||||
|
|
||||||
struct exp32_sig128 { int_fast32_t exp; struct uint128 sig; };
|
struct exp32_sig128 {
|
||||||
struct exp32_sig128
|
int_fast32_t exp;
|
||||||
softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t );
|
struct uint128 sig;
|
||||||
|
};
|
||||||
|
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t, uint_fast64_t);
|
||||||
|
|
||||||
float128_t
|
float128_t softfloat_roundPackToF128(bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t);
|
||||||
softfloat_roundPackToF128(
|
float128_t softfloat_normRoundPackToF128(bool, int_fast32_t, uint_fast64_t, uint_fast64_t);
|
||||||
bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t );
|
|
||||||
float128_t
|
|
||||||
softfloat_normRoundPackToF128(
|
|
||||||
bool, int_fast32_t, uint_fast64_t, uint_fast64_t );
|
|
||||||
|
|
||||||
float128_t
|
float128_t softfloat_addMagsF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool);
|
||||||
softfloat_addMagsF128(
|
float128_t softfloat_subMagsF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool);
|
||||||
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );
|
float128_t softfloat_mulAddF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
|
||||||
float128_t
|
|
||||||
softfloat_subMagsF128(
|
|
||||||
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );
|
|
||||||
float128_t
|
|
||||||
softfloat_mulAddF128(
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast64_t,
|
|
||||||
uint_fast8_t
|
|
||||||
);
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
bool
|
bool softfloat_tryPropagateNaNExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*);
|
||||||
softfloat_tryPropagateNaNExtF80M(
|
|
||||||
const struct extFloat80M *,
|
|
||||||
const struct extFloat80M *,
|
|
||||||
struct extFloat80M *
|
|
||||||
);
|
|
||||||
void softfloat_invalidExtF80M(struct extFloat80M*);
|
void softfloat_invalidExtF80M(struct extFloat80M*);
|
||||||
|
|
||||||
int softfloat_normExtF80SigM(uint64_t*);
|
int softfloat_normExtF80SigM(uint64_t*);
|
||||||
|
|
||||||
void
|
void softfloat_roundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
|
||||||
softfloat_roundPackMToExtF80M(
|
void softfloat_normRoundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
|
||||||
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
|
|
||||||
void
|
|
||||||
softfloat_normRoundPackMToExtF80M(
|
|
||||||
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
|
|
||||||
|
|
||||||
void
|
void softfloat_addExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*, bool);
|
||||||
softfloat_addExtF80M(
|
|
||||||
const struct extFloat80M *,
|
|
||||||
const struct extFloat80M *,
|
|
||||||
struct extFloat80M *,
|
|
||||||
bool
|
|
||||||
);
|
|
||||||
|
|
||||||
int
|
int softfloat_compareNonnormExtF80M(const struct extFloat80M*, const struct extFloat80M*);
|
||||||
softfloat_compareNonnormExtF80M(
|
|
||||||
const struct extFloat80M *, const struct extFloat80M * );
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -251,9 +241,7 @@ int
|
|||||||
|
|
||||||
bool softfloat_isNaNF128M(const uint32_t*);
|
bool softfloat_isNaNF128M(const uint32_t*);
|
||||||
|
|
||||||
bool
|
bool softfloat_tryPropagateNaNF128M(const uint32_t*, const uint32_t*, uint32_t*);
|
||||||
softfloat_tryPropagateNaNF128M(
|
|
||||||
const uint32_t *, const uint32_t *, uint32_t * );
|
|
||||||
void softfloat_invalidF128M(uint32_t*);
|
void softfloat_invalidF128M(uint32_t*);
|
||||||
|
|
||||||
int softfloat_shiftNormSigF128M(const uint32_t*, uint_fast8_t, uint32_t*);
|
int softfloat_shiftNormSigF128M(const uint32_t*, uint_fast8_t, uint32_t*);
|
||||||
@@ -261,18 +249,9 @@ int softfloat_shiftNormSigF128M( const uint32_t *, uint_fast8_t, uint32_t * );
|
|||||||
void softfloat_roundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
|
void softfloat_roundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
|
||||||
void softfloat_normRoundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
|
void softfloat_normRoundPackMToF128M(bool, int32_t, uint32_t*, uint32_t*);
|
||||||
|
|
||||||
void
|
void softfloat_addF128M(const uint32_t*, const uint32_t*, uint32_t*, bool);
|
||||||
softfloat_addF128M( const uint32_t *, const uint32_t *, uint32_t *, bool );
|
void softfloat_mulAddF128M(const uint32_t*, const uint32_t*, const uint32_t*, uint32_t*, uint_fast8_t);
|
||||||
void
|
|
||||||
softfloat_mulAddF128M(
|
|
||||||
const uint32_t *,
|
|
||||||
const uint32_t *,
|
|
||||||
const uint32_t *,
|
|
||||||
uint32_t *,
|
|
||||||
uint_fast8_t
|
|
||||||
);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -39,57 +39,57 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#ifdef INLINE
|
#ifdef INLINE
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "primitiveTypes.h"
|
#include "primitiveTypes.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_BUILTIN_CLZ
|
#ifdef SOFTFLOAT_BUILTIN_CLZ
|
||||||
|
|
||||||
INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a )
|
INLINE uint_fast8_t softfloat_countLeadingZeros16(uint16_t a) { return a ? __builtin_clz(a) - 16 : 16; }
|
||||||
{ return a ? __builtin_clz( a ) - 16 : 16; }
|
|
||||||
#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16
|
#define softfloat_countLeadingZeros16 softfloat_countLeadingZeros16
|
||||||
|
|
||||||
INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a )
|
INLINE uint_fast8_t softfloat_countLeadingZeros32(uint32_t a) { return a ? __builtin_clz(a) : 32; }
|
||||||
{ return a ? __builtin_clz( a ) : 32; }
|
|
||||||
#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
|
#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32
|
||||||
|
|
||||||
INLINE uint_fast8_t softfloat_countLeadingZeros64( uint64_t a )
|
INLINE uint_fast8_t softfloat_countLeadingZeros64(uint64_t a) { return a ? __builtin_clzll(a) : 64; }
|
||||||
{ return a ? __builtin_clzll( a ) : 64; }
|
|
||||||
#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
|
#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SOFTFLOAT_INTRINSIC_INT128
|
#ifdef SOFTFLOAT_INTRINSIC_INT128
|
||||||
|
|
||||||
INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b )
|
INLINE struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) {
|
||||||
{
|
union {
|
||||||
union { unsigned __int128 ui; struct uint128 s; } uZ;
|
unsigned __int128 ui;
|
||||||
|
struct uint128 s;
|
||||||
|
} uZ;
|
||||||
uZ.ui = (unsigned __int128)a * ((uint_fast64_t)b << 32);
|
uZ.ui = (unsigned __int128)a * ((uint_fast64_t)b << 32);
|
||||||
return uZ.s;
|
return uZ.s;
|
||||||
}
|
}
|
||||||
#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128
|
#define softfloat_mul64ByShifted32To128 softfloat_mul64ByShifted32To128
|
||||||
|
|
||||||
INLINE struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b )
|
INLINE struct uint128 softfloat_mul64To128(uint64_t a, uint64_t b) {
|
||||||
{
|
union {
|
||||||
union { unsigned __int128 ui; struct uint128 s; } uZ;
|
unsigned __int128 ui;
|
||||||
|
struct uint128 s;
|
||||||
|
} uZ;
|
||||||
uZ.ui = (unsigned __int128)a * b;
|
uZ.ui = (unsigned __int128)a * b;
|
||||||
return uZ.s;
|
return uZ.s;
|
||||||
}
|
}
|
||||||
#define softfloat_mul64To128 softfloat_mul64To128
|
#define softfloat_mul64To128 softfloat_mul64To128
|
||||||
|
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b )
|
struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) {
|
||||||
{
|
union {
|
||||||
union { unsigned __int128 ui; struct uint128 s; } uZ;
|
unsigned __int128 ui;
|
||||||
|
struct uint128 s;
|
||||||
|
} uZ;
|
||||||
uZ.ui = ((unsigned __int128)a64 << 64 | a0) * b;
|
uZ.ui = ((unsigned __int128)a64 << 64 | a0) * b;
|
||||||
return uZ.s;
|
return uZ.s;
|
||||||
}
|
}
|
||||||
#define softfloat_mul128By32 softfloat_mul128By32
|
#define softfloat_mul128By32 softfloat_mul128By32
|
||||||
|
|
||||||
INLINE
|
INLINE
|
||||||
void
|
void softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t* zPtr) {
|
||||||
softfloat_mul128To256M(
|
|
||||||
uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr )
|
|
||||||
{
|
|
||||||
unsigned __int128 z0, mid1, mid, z128;
|
unsigned __int128 z0, mid1, mid, z128;
|
||||||
z0 = (unsigned __int128)a0 * b0;
|
z0 = (unsigned __int128)a0 * b0;
|
||||||
mid1 = (unsigned __int128)a64 * b0;
|
mid1 = (unsigned __int128)a64 * b0;
|
||||||
@@ -111,4 +111,3 @@ void
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -42,13 +42,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifdef SOFTFLOAT_FAST_INT64
|
#ifdef SOFTFLOAT_FAST_INT64
|
||||||
|
|
||||||
#ifdef LITTLEENDIAN
|
#ifdef LITTLEENDIAN
|
||||||
struct uint128 { uint64_t v0, v64; };
|
struct uint128 {
|
||||||
struct uint64_extra { uint64_t extra, v; };
|
uint64_t v0, v64;
|
||||||
struct uint128_extra { uint64_t extra; struct uint128 v; };
|
};
|
||||||
|
struct uint64_extra {
|
||||||
|
uint64_t extra, v;
|
||||||
|
};
|
||||||
|
struct uint128_extra {
|
||||||
|
uint64_t extra;
|
||||||
|
struct uint128 v;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
struct uint128 { uint64_t v64, v0; };
|
struct uint128 {
|
||||||
struct uint64_extra { uint64_t v, extra; };
|
uint64_t v64, v0;
|
||||||
struct uint128_extra { struct uint128 v; uint64_t extra; };
|
};
|
||||||
|
struct uint64_extra {
|
||||||
|
uint64_t v, extra;
|
||||||
|
};
|
||||||
|
struct uint128_extra {
|
||||||
|
struct uint128 v;
|
||||||
|
uint64_t extra;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -67,7 +81,8 @@ struct uint128_extra { struct uint128 v; uint64_t extra; };
|
|||||||
#define indexMultiwordLo(total, n) 0
|
#define indexMultiwordLo(total, n) 0
|
||||||
#define indexMultiwordHiBut(total, n) (n)
|
#define indexMultiwordHiBut(total, n) (n)
|
||||||
#define indexMultiwordLoBut(total, n) 0
|
#define indexMultiwordLoBut(total, n) 0
|
||||||
#define INIT_UINTM4( v3, v2, v1, v0 ) { v0, v1, v2, v3 }
|
#define INIT_UINTM4(v3, v2, v1, v0) \
|
||||||
|
{ v0, v1, v2, v3 }
|
||||||
#else
|
#else
|
||||||
#define wordIncr -1
|
#define wordIncr -1
|
||||||
#define indexWord(total, n) ((total)-1 - (n))
|
#define indexWord(total, n) ((total)-1 - (n))
|
||||||
@@ -78,8 +93,8 @@ struct uint128_extra { struct uint128 v; uint64_t extra; };
|
|||||||
#define indexMultiwordLo(total, n) ((total) - (n))
|
#define indexMultiwordLo(total, n) ((total) - (n))
|
||||||
#define indexMultiwordHiBut(total, n) 0
|
#define indexMultiwordHiBut(total, n) 0
|
||||||
#define indexMultiwordLoBut(total, n) (n)
|
#define indexMultiwordLoBut(total, n) (n)
|
||||||
#define INIT_UINTM4( v3, v2, v1, v0 ) { v3, v2, v1, v0 }
|
#define INIT_UINTM4(v3, v2, v1, v0) \
|
||||||
|
{ v3, v2, v1, v0 }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -37,9 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifndef primitives_h
|
#ifndef primitives_h
|
||||||
#define primitives_h 1
|
#define primitives_h 1
|
||||||
|
|
||||||
|
#include "primitiveTypes.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "primitiveTypes.h"
|
|
||||||
|
|
||||||
#ifndef softfloat_shortShiftRightJam64
|
#ifndef softfloat_shortShiftRightJam64
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -50,8 +50,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist )
|
uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist) { return a >> dist | ((a & (((uint_fast64_t)1 << dist) - 1)) != 0); }
|
||||||
{ return a>>dist | ((a & (((uint_fast64_t) 1<<dist) - 1)) != 0); }
|
|
||||||
#else
|
#else
|
||||||
uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist);
|
uint64_t softfloat_shortShiftRightJam64(uint64_t a, uint_fast8_t dist);
|
||||||
#endif
|
#endif
|
||||||
@@ -68,10 +67,8 @@ uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t dist );
|
|||||||
| is zero or nonzero.
|
| is zero or nonzero.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist )
|
INLINE uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist) {
|
||||||
{
|
return (dist < 31) ? a >> dist | ((uint32_t)(a << (-dist & 31)) != 0) : (a != 0);
|
||||||
return
|
|
||||||
(dist < 31) ? a>>dist | ((uint32_t) (a<<(-dist & 31)) != 0) : (a != 0);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist);
|
uint32_t softfloat_shiftRightJam32(uint32_t a, uint_fast16_t dist);
|
||||||
@@ -89,10 +86,8 @@ uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t dist );
|
|||||||
| is zero or nonzero.
|
| is zero or nonzero.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
||||||
INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t dist )
|
INLINE uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist) {
|
||||||
{
|
return (dist < 63) ? a >> dist | ((uint64_t)(a << (-dist & 63)) != 0) : (a != 0);
|
||||||
return
|
|
||||||
(dist < 63) ? a>>dist | ((uint64_t) (a<<(-dist & 63)) != 0) : (a != 0);
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist);
|
uint64_t softfloat_shiftRightJam64(uint64_t a, uint_fast32_t dist);
|
||||||
@@ -112,8 +107,7 @@ extern const uint_least8_t softfloat_countLeadingZeros8[256];
|
|||||||
| 'a'. If 'a' is zero, 16 is returned.
|
| 'a'. If 'a' is zero, 16 is returned.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE uint_fast8_t softfloat_countLeadingZeros16( uint16_t a )
|
INLINE uint_fast8_t softfloat_countLeadingZeros16(uint16_t a) {
|
||||||
{
|
|
||||||
uint_fast8_t count = 8;
|
uint_fast8_t count = 8;
|
||||||
if(0x100 <= a) {
|
if(0x100 <= a) {
|
||||||
count = 0;
|
count = 0;
|
||||||
@@ -133,8 +127,7 @@ uint_fast8_t softfloat_countLeadingZeros16( uint16_t a );
|
|||||||
| 'a'. If 'a' is zero, 32 is returned.
|
| 'a'. If 'a' is zero, 32 is returned.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
||||||
INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a )
|
INLINE uint_fast8_t softfloat_countLeadingZeros32(uint32_t a) {
|
||||||
{
|
|
||||||
uint_fast8_t count = 0;
|
uint_fast8_t count = 0;
|
||||||
if(a < 0x10000) {
|
if(a < 0x10000) {
|
||||||
count = 16;
|
count = 16;
|
||||||
@@ -222,8 +215,7 @@ uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a );
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
|
bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 == b64) && (a0 == b0); }
|
||||||
{ return (a64 == b64) && (a0 == b0); }
|
|
||||||
#else
|
#else
|
||||||
bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
bool softfloat_eq128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
||||||
#endif
|
#endif
|
||||||
@@ -237,8 +229,7 @@ bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
|
bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); }
|
||||||
{ return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); }
|
|
||||||
#else
|
#else
|
||||||
bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
bool softfloat_le128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
||||||
#endif
|
#endif
|
||||||
@@ -252,8 +243,7 @@ bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
|
bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); }
|
||||||
{ return (a64 < b64) || ((a64 == b64) && (a0 < b0)); }
|
|
||||||
#else
|
#else
|
||||||
bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
bool softfloat_lt128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
||||||
#endif
|
#endif
|
||||||
@@ -266,17 +256,14 @@ bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
|
||||||
softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist )
|
|
||||||
{
|
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
z.v64 = a64 << dist | a0 >> (-dist & 63);
|
z.v64 = a64 << dist | a0 >> (-dist & 63);
|
||||||
z.v0 = a0 << dist;
|
z.v0 = a0 << dist;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftLeft128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
|
||||||
softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -287,17 +274,14 @@ struct uint128
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
|
||||||
softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist )
|
|
||||||
{
|
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
z.v64 = a64 >> dist;
|
z.v64 = a64 >> dist;
|
||||||
z.v0 = a64 << (-dist & 63) | a0 >> dist;
|
z.v0 = a64 << (-dist & 63) | a0 >> dist;
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftRight128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
|
||||||
softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -308,19 +292,14 @@ struct uint128
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint64_extra
|
struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast8_t dist) {
|
||||||
softfloat_shortShiftRightJam64Extra(
|
|
||||||
uint64_t a, uint64_t extra, uint_fast8_t dist )
|
|
||||||
{
|
|
||||||
struct uint64_extra z;
|
struct uint64_extra z;
|
||||||
z.v = a >> dist;
|
z.v = a >> dist;
|
||||||
z.extra = a << (-dist & 63) | (extra != 0);
|
z.extra = a << (-dist & 63) | (extra != 0);
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint64_extra
|
struct uint64_extra softfloat_shortShiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast8_t dist);
|
||||||
softfloat_shortShiftRightJam64Extra(
|
|
||||||
uint64_t a, uint64_t extra, uint_fast8_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -334,22 +313,15 @@ struct uint64_extra
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint_fast8_t dist) {
|
||||||
softfloat_shortShiftRightJam128(
|
|
||||||
uint64_t a64, uint64_t a0, uint_fast8_t dist )
|
|
||||||
{
|
|
||||||
uint_fast8_t negDist = -dist;
|
uint_fast8_t negDist = -dist;
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
z.v64 = a64 >> dist;
|
z.v64 = a64 >> dist;
|
||||||
z.v0 =
|
z.v0 = a64 << (negDist & 63) | a0 >> dist | ((uint64_t)(a0 << (negDist & 63)) != 0);
|
||||||
a64<<(negDist & 63) | a0>>dist
|
|
||||||
| ((uint64_t) (a0<<(negDist & 63)) != 0);
|
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128
|
struct uint128 softfloat_shortShiftRightJam128(uint64_t a64, uint64_t a0, uint_fast8_t dist);
|
||||||
softfloat_shortShiftRightJam128(
|
|
||||||
uint64_t a64, uint64_t a0, uint_fast8_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -360,10 +332,7 @@ struct uint128
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128_extra
|
struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist) {
|
||||||
softfloat_shortShiftRightJam128Extra(
|
|
||||||
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist )
|
|
||||||
{
|
|
||||||
uint_fast8_t negDist = -dist;
|
uint_fast8_t negDist = -dist;
|
||||||
struct uint128_extra z;
|
struct uint128_extra z;
|
||||||
z.v.v64 = a64 >> dist;
|
z.v.v64 = a64 >> dist;
|
||||||
@@ -372,9 +341,7 @@ struct uint128_extra
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128_extra
|
struct uint128_extra softfloat_shortShiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist);
|
||||||
softfloat_shortShiftRightJam128Extra(
|
|
||||||
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -397,10 +364,7 @@ struct uint128_extra
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint64_extra
|
struct uint64_extra softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast32_t dist) {
|
||||||
softfloat_shiftRightJam64Extra(
|
|
||||||
uint64_t a, uint64_t extra, uint_fast32_t dist )
|
|
||||||
{
|
|
||||||
struct uint64_extra z;
|
struct uint64_extra z;
|
||||||
if(dist < 64) {
|
if(dist < 64) {
|
||||||
z.v = a >> dist;
|
z.v = a >> dist;
|
||||||
@@ -413,9 +377,7 @@ struct uint64_extra
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint64_extra
|
struct uint64_extra softfloat_shiftRightJam64Extra(uint64_t a, uint64_t extra, uint_fast32_t dist);
|
||||||
softfloat_shiftRightJam64Extra(
|
|
||||||
uint64_t a, uint64_t extra, uint_fast32_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -430,8 +392,7 @@ struct uint64_extra
|
|||||||
| greater than 128, the result will be either 0 or 1, depending on whether the
|
| greater than 128, the result will be either 0 or 1, depending on whether the
|
||||||
| original 128 bits are all zeros.
|
| original 128 bits are all zeros.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128
|
struct uint128 softfloat_shiftRightJam128(uint64_t a64, uint64_t a0, uint_fast32_t dist);
|
||||||
softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shiftRightJam128Extra
|
#ifndef softfloat_shiftRightJam128Extra
|
||||||
@@ -452,9 +413,7 @@ struct uint128
|
|||||||
| is modified as described above and returned in the 'extra' field of the
|
| is modified as described above and returned in the 'extra' field of the
|
||||||
| result.)
|
| result.)
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
struct uint128_extra
|
struct uint128_extra softfloat_shiftRightJam128Extra(uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist);
|
||||||
softfloat_shiftRightJam128Extra(
|
|
||||||
uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t dist );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shiftRightJam256M
|
#ifndef softfloat_shiftRightJam256M
|
||||||
@@ -470,9 +429,7 @@ struct uint128_extra
|
|||||||
| is greater than 256, the stored result will be either 0 or 1, depending on
|
| is greater than 256, the stored result will be either 0 or 1, depending on
|
||||||
| whether the original 256 bits are all zeros.
|
| whether the original 256 bits are all zeros.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shiftRightJam256M(const uint64_t* aPtr, uint_fast32_t dist, uint64_t* zPtr);
|
||||||
softfloat_shiftRightJam256M(
|
|
||||||
const uint64_t *aPtr, uint_fast32_t dist, uint64_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_add128
|
#ifndef softfloat_add128
|
||||||
@@ -483,17 +440,14 @@ void
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128
|
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) {
|
||||||
softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
|
|
||||||
{
|
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
z.v0 = a0 + b0;
|
z.v0 = a0 + b0;
|
||||||
z.v64 = a64 + b64 + (z.v0 < a0);
|
z.v64 = a64 + b64 + (z.v0 < a0);
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128
|
struct uint128 softfloat_add128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
||||||
softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -505,9 +459,7 @@ struct uint128
|
|||||||
| an array of four 64-bit elements that concatenate in the platform's normal
|
| an array of four 64-bit elements that concatenate in the platform's normal
|
||||||
| endian order to form a 256-bit integer.
|
| endian order to form a 256-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_add256M(const uint64_t* aPtr, const uint64_t* bPtr, uint64_t* zPtr);
|
||||||
softfloat_add256M(
|
|
||||||
const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_sub128
|
#ifndef softfloat_sub128
|
||||||
@@ -518,9 +470,7 @@ void
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128
|
struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0) {
|
||||||
softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 )
|
|
||||||
{
|
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
z.v0 = a0 - b0;
|
z.v0 = a0 - b0;
|
||||||
z.v64 = a64 - b64;
|
z.v64 = a64 - b64;
|
||||||
@@ -528,8 +478,7 @@ struct uint128
|
|||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct uint128
|
struct uint128 softfloat_sub128(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0);
|
||||||
softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -542,9 +491,7 @@ struct uint128
|
|||||||
| 64-bit elements that concatenate in the platform's normal endian order to
|
| 64-bit elements that concatenate in the platform's normal endian order to
|
||||||
| form a 256-bit integer.
|
| form a 256-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_sub256M(const uint64_t* aPtr, const uint64_t* bPtr, uint64_t* zPtr);
|
||||||
softfloat_sub256M(
|
|
||||||
const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_mul64ByShifted32To128
|
#ifndef softfloat_mul64ByShifted32To128
|
||||||
@@ -552,8 +499,7 @@ void
|
|||||||
| Returns the 128-bit product of 'a', 'b', and 2^32.
|
| Returns the 128-bit product of 'a', 'b', and 2^32.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL)
|
||||||
INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b )
|
INLINE struct uint128 softfloat_mul64ByShifted32To128(uint64_t a, uint32_t b) {
|
||||||
{
|
|
||||||
uint_fast64_t mid;
|
uint_fast64_t mid;
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
mid = (uint_fast64_t)(uint32_t)a * b;
|
mid = (uint_fast64_t)(uint32_t)a * b;
|
||||||
@@ -581,8 +527,7 @@ struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b );
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b )
|
struct uint128 softfloat_mul128By32(uint64_t a64, uint64_t a0, uint32_t b) {
|
||||||
{
|
|
||||||
struct uint128 z;
|
struct uint128 z;
|
||||||
uint_fast64_t mid;
|
uint_fast64_t mid;
|
||||||
uint_fast32_t carry;
|
uint_fast32_t carry;
|
||||||
@@ -605,9 +550,7 @@ struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b );
|
|||||||
| Argument 'zPtr' points to an array of four 64-bit elements that concatenate
|
| Argument 'zPtr' points to an array of four 64-bit elements that concatenate
|
||||||
| in the platform's normal endian order to form a 256-bit integer.
|
| in the platform's normal endian order to form a 256-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_mul128To256M(uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t* zPtr);
|
||||||
softfloat_mul128To256M(
|
|
||||||
uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@@ -638,8 +581,7 @@ int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr );
|
|||||||
| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that
|
| Each of 'aPtr' and 'bPtr' points to an array of four 32-bit elements that
|
||||||
| concatenate in the platform's normal endian order to form a 128-bit integer.
|
| concatenate in the platform's normal endian order to form a 128-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
int_fast8_t
|
int_fast8_t softfloat_compare128M(const uint32_t* aPtr, const uint32_t* bPtr);
|
||||||
softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shortShiftLeft64To96M
|
#ifndef softfloat_shortShiftLeft64To96M
|
||||||
@@ -652,19 +594,14 @@ int_fast8_t
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL)
|
||||||
INLINE
|
INLINE
|
||||||
void
|
void softfloat_shortShiftLeft64To96M(uint64_t a, uint_fast8_t dist, uint32_t* zPtr) {
|
||||||
softfloat_shortShiftLeft64To96M(
|
|
||||||
uint64_t a, uint_fast8_t dist, uint32_t *zPtr )
|
|
||||||
{
|
|
||||||
zPtr[indexWord(3, 0)] = (uint32_t)a << dist;
|
zPtr[indexWord(3, 0)] = (uint32_t)a << dist;
|
||||||
a >>= 32 - dist;
|
a >>= 32 - dist;
|
||||||
zPtr[indexWord(3, 2)] = a >> 32;
|
zPtr[indexWord(3, 2)] = a >> 32;
|
||||||
zPtr[indexWord(3, 1)] = a;
|
zPtr[indexWord(3, 1)] = a;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void
|
void softfloat_shortShiftLeft64To96M(uint64_t a, uint_fast8_t dist, uint32_t* zPtr);
|
||||||
softfloat_shortShiftLeft64To96M(
|
|
||||||
uint64_t a, uint_fast8_t dist, uint32_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -678,13 +615,7 @@ void
|
|||||||
| that concatenate in the platform's normal endian order to form an N-bit
|
| that concatenate in the platform's normal endian order to form an N-bit
|
||||||
| integer.
|
| integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shortShiftLeftM(uint_fast8_t size_words, const uint32_t* aPtr, uint_fast8_t dist, uint32_t* zPtr);
|
||||||
softfloat_shortShiftLeftM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
uint_fast8_t dist,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shortShiftLeft96M
|
#ifndef softfloat_shortShiftLeft96M
|
||||||
@@ -722,13 +653,7 @@ void
|
|||||||
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
|
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
|
||||||
| greater than N, the stored result will be 0.
|
| greater than N, the stored result will be 0.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shiftLeftM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
|
||||||
softfloat_shiftLeftM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
uint32_t dist,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shiftLeft96M
|
#ifndef softfloat_shiftLeft96M
|
||||||
@@ -765,13 +690,7 @@ void
|
|||||||
| that concatenate in the platform's normal endian order to form an N-bit
|
| that concatenate in the platform's normal endian order to form an N-bit
|
||||||
| integer.
|
| integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shortShiftRightM(uint_fast8_t size_words, const uint32_t* aPtr, uint_fast8_t dist, uint32_t* zPtr);
|
||||||
softfloat_shortShiftRightM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
uint_fast8_t dist,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shortShiftRight128M
|
#ifndef softfloat_shortShiftRight128M
|
||||||
@@ -801,9 +720,7 @@ void
|
|||||||
| to a 'size_words'-long array of 32-bit elements that concatenate in the
|
| to a 'size_words'-long array of 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form an N-bit integer.
|
| platform's normal endian order to form an N-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shortShiftRightJamM(uint_fast8_t, const uint32_t*, uint_fast8_t, uint32_t*);
|
||||||
softfloat_shortShiftRightJamM(
|
|
||||||
uint_fast8_t, const uint32_t *, uint_fast8_t, uint32_t * );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shortShiftRightJam160M
|
#ifndef softfloat_shortShiftRightJam160M
|
||||||
@@ -825,13 +742,7 @@ void
|
|||||||
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
|
| The value of 'dist' can be arbitrarily large. In particular, if 'dist' is
|
||||||
| greater than N, the stored result will be 0.
|
| greater than N, the stored result will be 0.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shiftRightM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
|
||||||
softfloat_shiftRightM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
uint32_t dist,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shiftRight96M
|
#ifndef softfloat_shiftRight96M
|
||||||
@@ -856,13 +767,7 @@ void
|
|||||||
| is greater than N, the stored result will be either 0 or 1, depending on
|
| is greater than N, the stored result will be either 0 or 1, depending on
|
||||||
| whether the original N bits are all zeros.
|
| whether the original N bits are all zeros.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_shiftRightJamM(uint_fast8_t size_words, const uint32_t* aPtr, uint32_t dist, uint32_t* zPtr);
|
||||||
softfloat_shiftRightJamM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
uint32_t dist,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_shiftRightJam96M
|
#ifndef softfloat_shiftRightJam96M
|
||||||
@@ -898,13 +803,7 @@ void
|
|||||||
| elements that concatenate in the platform's normal endian order to form an
|
| elements that concatenate in the platform's normal endian order to form an
|
||||||
| N-bit integer.
|
| N-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_addM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
|
||||||
softfloat_addM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
const uint32_t *bPtr,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_add96M
|
#ifndef softfloat_add96M
|
||||||
@@ -940,14 +839,7 @@ void
|
|||||||
| points to a 'size_words'-long array of 32-bit elements that concatenate in
|
| points to a 'size_words'-long array of 32-bit elements that concatenate in
|
||||||
| the platform's normal endian order to form an N-bit integer.
|
| the platform's normal endian order to form an N-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast8_t
|
uint_fast8_t softfloat_addCarryM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint_fast8_t carry, uint32_t* zPtr);
|
||||||
softfloat_addCarryM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
const uint32_t *bPtr,
|
|
||||||
uint_fast8_t carry,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_addComplCarryM
|
#ifndef softfloat_addComplCarryM
|
||||||
@@ -956,14 +848,8 @@ uint_fast8_t
|
|||||||
| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed
|
| the value of the unsigned integer pointed to by 'bPtr' is bit-wise completed
|
||||||
| before the addition.
|
| before the addition.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
uint_fast8_t
|
uint_fast8_t softfloat_addComplCarryM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint_fast8_t carry,
|
||||||
softfloat_addComplCarryM(
|
uint32_t* zPtr);
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
const uint32_t *bPtr,
|
|
||||||
uint_fast8_t carry,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_addComplCarry96M
|
#ifndef softfloat_addComplCarry96M
|
||||||
@@ -1052,13 +938,7 @@ void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr );
|
|||||||
| array of 32-bit elements that concatenate in the platform's normal endian
|
| array of 32-bit elements that concatenate in the platform's normal endian
|
||||||
| order to form an N-bit integer.
|
| order to form an N-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_subM(uint_fast8_t size_words, const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
|
||||||
softfloat_subM(
|
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *aPtr,
|
|
||||||
const uint32_t *bPtr,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_sub96M
|
#ifndef softfloat_sub96M
|
||||||
@@ -1104,9 +984,7 @@ void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr );
|
|||||||
| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate
|
| Argument 'zPtr' points to an array of eight 32-bit elements that concatenate
|
||||||
| to form a 256-bit integer.
|
| to form a 256-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_mul128MTo256M(const uint32_t* aPtr, const uint32_t* bPtr, uint32_t* zPtr);
|
||||||
softfloat_mul128MTo256M(
|
|
||||||
const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_remStepMBy32
|
#ifndef softfloat_remStepMBy32
|
||||||
@@ -1119,15 +997,8 @@ void
|
|||||||
| to a 'size_words'-long array of 32-bit elements that concatenate in the
|
| to a 'size_words'-long array of 32-bit elements that concatenate in the
|
||||||
| platform's normal endian order to form an N-bit integer.
|
| platform's normal endian order to form an N-bit integer.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
void
|
void softfloat_remStepMBy32(uint_fast8_t size_words, const uint32_t* remPtr, uint_fast8_t dist, const uint32_t* bPtr, uint32_t q,
|
||||||
softfloat_remStepMBy32(
|
uint32_t* zPtr);
|
||||||
uint_fast8_t size_words,
|
|
||||||
const uint32_t *remPtr,
|
|
||||||
uint_fast8_t dist,
|
|
||||||
const uint32_t *bPtr,
|
|
||||||
uint32_t q,
|
|
||||||
uint32_t *zPtr
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef softfloat_remStep96MBy32
|
#ifndef softfloat_remStep96MBy32
|
||||||
@@ -1157,4 +1028,3 @@ void
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -34,7 +34,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
=============================================================================*/
|
=============================================================================*/
|
||||||
|
|
||||||
|
|
||||||
/*============================================================================
|
/*============================================================================
|
||||||
| Note: If SoftFloat is made available as a general library for programs to
|
| Note: If SoftFloat is made available as a general library for programs to
|
||||||
| use, it is strongly recommended that a platform-specific version of this
|
| use, it is strongly recommended that a platform-specific version of this
|
||||||
@@ -42,13 +41,12 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| eliminates all dependencies on compile-time macros.
|
| eliminates all dependencies on compile-time macros.
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef softfloat_h
|
#ifndef softfloat_h
|
||||||
#define softfloat_h 1
|
#define softfloat_h 1
|
||||||
|
|
||||||
|
#include "softfloat_types.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "softfloat_types.h"
|
|
||||||
|
|
||||||
#ifndef THREAD_LOCAL
|
#ifndef THREAD_LOCAL
|
||||||
#define THREAD_LOCAL
|
#define THREAD_LOCAL
|
||||||
@@ -58,10 +56,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| Software floating-point underflow tininess-detection mode.
|
| Software floating-point underflow tininess-detection mode.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;
|
extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;
|
||||||
enum {
|
enum { softfloat_tininess_beforeRounding = 0, softfloat_tininess_afterRounding = 1 };
|
||||||
softfloat_tininess_beforeRounding = 0,
|
|
||||||
softfloat_tininess_afterRounding = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Software floating-point rounding mode. (Mode "odd" is supported only if
|
| Software floating-point rounding mode. (Mode "odd" is supported only if
|
||||||
@@ -81,13 +76,13 @@ enum {
|
|||||||
| Software floating-point exception flags.
|
| Software floating-point exception flags.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags;
|
extern THREAD_LOCAL uint_fast8_t softfloat_exceptionFlags;
|
||||||
enum {
|
typedef enum {
|
||||||
softfloat_flag_inexact = 1,
|
softfloat_flag_inexact = 1,
|
||||||
softfloat_flag_underflow = 2,
|
softfloat_flag_underflow = 2,
|
||||||
softfloat_flag_overflow = 4,
|
softfloat_flag_overflow = 4,
|
||||||
softfloat_flag_infinite = 8,
|
softfloat_flag_infinite = 8,
|
||||||
softfloat_flag_invalid = 16
|
softfloat_flag_invalid = 16
|
||||||
};
|
} exceptionFlag_t;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| Routine to raise any or all of the software floating-point exception flags.
|
| Routine to raise any or all of the software floating-point exception flags.
|
||||||
@@ -169,6 +164,13 @@ bool f16_le_quiet( float16_t, float16_t );
|
|||||||
bool f16_lt_quiet(float16_t, float16_t);
|
bool f16_lt_quiet(float16_t, float16_t);
|
||||||
bool f16_isSignalingNaN(float16_t);
|
bool f16_isSignalingNaN(float16_t);
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| 16-bit (brain float 16) floating-point operations.
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
float32_t bf16_to_f32(bfloat16_t);
|
||||||
|
bfloat16_t f32_to_bf16(float32_t);
|
||||||
|
bool bf16_isSignalingNaN(bfloat16_t);
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| 32-bit (single-precision) floating-point operations.
|
| 32-bit (single-precision) floating-point operations.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
@@ -288,9 +290,7 @@ float16_t extF80M_to_f16( const extFloat80_t * );
|
|||||||
float32_t extF80M_to_f32(const extFloat80_t*);
|
float32_t extF80M_to_f32(const extFloat80_t*);
|
||||||
float64_t extF80M_to_f64(const extFloat80_t*);
|
float64_t extF80M_to_f64(const extFloat80_t*);
|
||||||
void extF80M_to_f128M(const extFloat80_t*, float128_t*);
|
void extF80M_to_f128M(const extFloat80_t*, float128_t*);
|
||||||
void
|
void extF80M_roundToInt(const extFloat80_t*, uint_fast8_t, bool, extFloat80_t*);
|
||||||
extF80M_roundToInt(
|
|
||||||
const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );
|
|
||||||
void extF80M_add(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
void extF80M_add(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
||||||
void extF80M_sub(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
void extF80M_sub(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
||||||
void extF80M_mul(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
void extF80M_mul(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
|
||||||
@@ -353,10 +353,7 @@ void f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * );
|
|||||||
void f128M_add(const float128_t*, const float128_t*, float128_t*);
|
void f128M_add(const float128_t*, const float128_t*, float128_t*);
|
||||||
void f128M_sub(const float128_t*, const float128_t*, float128_t*);
|
void f128M_sub(const float128_t*, const float128_t*, float128_t*);
|
||||||
void f128M_mul(const float128_t*, const float128_t*, float128_t*);
|
void f128M_mul(const float128_t*, const float128_t*, float128_t*);
|
||||||
void
|
void f128M_mulAdd(const float128_t*, const float128_t*, const float128_t*, float128_t*);
|
||||||
f128M_mulAdd(
|
|
||||||
const float128_t *, const float128_t *, const float128_t *, float128_t *
|
|
||||||
);
|
|
||||||
void f128M_div(const float128_t*, const float128_t*, float128_t*);
|
void f128M_div(const float128_t*, const float128_t*, float128_t*);
|
||||||
void f128M_rem(const float128_t*, const float128_t*, float128_t*);
|
void f128M_rem(const float128_t*, const float128_t*, float128_t*);
|
||||||
void f128M_sqrt(const float128_t*, float128_t*);
|
void f128M_sqrt(const float128_t*, float128_t*);
|
||||||
@@ -369,4 +366,3 @@ bool f128M_lt_quiet( const float128_t *, const float128_t * );
|
|||||||
bool f128M_isSignalingNaN(const float128_t*);
|
bool f128M_isSignalingNaN(const float128_t*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -47,10 +47,21 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
| the types below may, if desired, be defined as aliases for the native types
|
| the types below may, if desired, be defined as aliases for the native types
|
||||||
| (typically 'float' and 'double', and possibly 'long double').
|
| (typically 'float' and 'double', and possibly 'long double').
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
typedef struct { uint16_t v; } float16_t;
|
typedef struct {
|
||||||
typedef struct { uint32_t v; } float32_t;
|
uint16_t v;
|
||||||
typedef struct { uint64_t v; } float64_t;
|
} float16_t;
|
||||||
typedef struct { uint64_t v[2]; } float128_t;
|
typedef struct {
|
||||||
|
uint16_t v;
|
||||||
|
} bfloat16_t;
|
||||||
|
typedef struct {
|
||||||
|
uint32_t v;
|
||||||
|
} float32_t;
|
||||||
|
typedef struct {
|
||||||
|
uint64_t v;
|
||||||
|
} float64_t;
|
||||||
|
typedef struct {
|
||||||
|
uint64_t v[2];
|
||||||
|
} float128_t;
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
| The format of an 80-bit extended floating-point number in memory. This
|
| The format of an 80-bit extended floating-point number in memory. This
|
||||||
@@ -58,9 +69,15 @@ typedef struct { uint64_t v[2]; } float128_t;
|
|||||||
| named 'signif'.
|
| named 'signif'.
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
#ifdef LITTLEENDIAN
|
#ifdef LITTLEENDIAN
|
||||||
struct extFloat80M { uint64_t signif; uint16_t signExp; };
|
struct extFloat80M {
|
||||||
|
uint64_t signif;
|
||||||
|
uint16_t signExp;
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
struct extFloat80M { uint16_t signExp; uint64_t signif; };
|
struct extFloat80M {
|
||||||
|
uint16_t signExp;
|
||||||
|
uint64_t signif;
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------
|
||||||
@@ -78,4 +95,3 @@ struct extFloat80M { uint16_t signExp; uint64_t signif; };
|
|||||||
typedef struct extFloat80M extFloat80_t;
|
typedef struct extFloat80M extFloat80_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -221,4 +221,3 @@ float32_t
|
|||||||
return uZ.f;
|
return uZ.f;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of
|
||||||
|
California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "internals.h"
|
||||||
|
|
||||||
|
struct exp8_sig16 softfloat_normSubnormalBF16Sig( uint_fast16_t sig )
|
||||||
|
{
|
||||||
|
int_fast8_t shiftDist;
|
||||||
|
struct exp8_sig16 z;
|
||||||
|
|
||||||
|
shiftDist = softfloat_countLeadingZeros16( sig ) - 8;
|
||||||
|
z.exp = 1 - shiftDist;
|
||||||
|
z.sig = sig<<shiftDist;
|
||||||
|
return z;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
/*============================================================================
|
||||||
|
|
||||||
|
This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic
|
||||||
|
Package, Release 3e, by John R. Hauser.
|
||||||
|
|
||||||
|
Copyright 2011, 2012, 2013, 2014, 2015, 2017 The Regents of the University of
|
||||||
|
California. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions, and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
3. Neither the name of the University nor the names of its contributors may
|
||||||
|
be used to endorse or promote products derived from this software without
|
||||||
|
specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "platform.h"
|
||||||
|
#include "internals.h"
|
||||||
|
#include "softfloat.h"
|
||||||
|
|
||||||
|
/** sig last significant bit is sig[7], the 7 LSBs will be used for rounding */
|
||||||
|
bfloat16_t
|
||||||
|
softfloat_roundPackToBF16( bool sign, int_fast16_t exp, uint_fast16_t sig )
|
||||||
|
{
|
||||||
|
uint_fast8_t roundingMode;
|
||||||
|
bool roundNearEven;
|
||||||
|
uint_fast8_t roundIncrement, roundBits;
|
||||||
|
bool isTiny;
|
||||||
|
uint_fast16_t uiZ;
|
||||||
|
union ui16_bf16 uZ;
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
roundingMode = softfloat_roundingMode;
|
||||||
|
roundNearEven = (roundingMode == softfloat_round_near_even);
|
||||||
|
roundIncrement = 0x40;
|
||||||
|
if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {
|
||||||
|
roundIncrement =
|
||||||
|
(roundingMode
|
||||||
|
== (sign ? softfloat_round_min : softfloat_round_max))
|
||||||
|
? 0x7F
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
roundBits = sig & 0x7F;
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
if ( 0xFD <= (unsigned int) exp ) {
|
||||||
|
if ( exp < 0 ) {
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------*/
|
||||||
|
isTiny =
|
||||||
|
(softfloat_detectTininess == softfloat_tininess_beforeRounding)
|
||||||
|
|| (exp < -1) || (sig + roundIncrement < 0x8000);
|
||||||
|
sig = softfloat_shiftRightJam32( sig, -exp );
|
||||||
|
exp = 0;
|
||||||
|
roundBits = sig & 0x7F;
|
||||||
|
if ( isTiny && roundBits ) {
|
||||||
|
softfloat_raiseFlags( softfloat_flag_underflow );
|
||||||
|
}
|
||||||
|
} else if ( (0xFD < exp) || (0x8000 <= sig + roundIncrement) ) {
|
||||||
|
/*----------------------------------------------------------------
|
||||||
|
*----------------------------------------------------------------*/
|
||||||
|
softfloat_raiseFlags(
|
||||||
|
softfloat_flag_overflow | softfloat_flag_inexact );
|
||||||
|
uiZ = packToBF16UI( sign, 0xFF, 0 ) - ! roundIncrement;
|
||||||
|
goto uiZ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
sig = (sig + roundIncrement)>>7;
|
||||||
|
if ( roundBits ) {
|
||||||
|
softfloat_exceptionFlags |= softfloat_flag_inexact;
|
||||||
|
#ifdef SOFTFLOAT_ROUND_ODD
|
||||||
|
if ( roundingMode == softfloat_round_odd ) {
|
||||||
|
sig |= 1;
|
||||||
|
goto packReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
sig &= ~(uint_fast16_t) (! (roundBits ^ 0x40) & roundNearEven);
|
||||||
|
if ( ! sig ) exp = 0;
|
||||||
|
/*------------------------------------------------------------------------
|
||||||
|
*------------------------------------------------------------------------*/
|
||||||
|
packReturn:
|
||||||
|
uiZ = packToBF16UI( sign, exp, sig );
|
||||||
|
uiZ:
|
||||||
|
uZ.ui = uiZ;
|
||||||
|
return uZ.f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifdef _MSC_VER
|
||||||
|
#define _SCL_SECURE_NO_WARNINGS
|
||||||
|
#define ELFIO_NO_INTTYPES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <elfio/elfio_dump.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace ELFIO;
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
if(argc != 2) {
|
||||||
|
printf("Usage: elfdump <file_name>\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
elfio reader;
|
||||||
|
|
||||||
|
if(!reader.load(argv[1])) {
|
||||||
|
printf("File %s is not found or it is not an ELF file\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dump::header(std::cout, reader);
|
||||||
|
dump::section_headers(std::cout, reader);
|
||||||
|
dump::segment_headers(std::cout, reader);
|
||||||
|
dump::symbol_tables(std::cout, reader);
|
||||||
|
dump::notes(std::cout, reader);
|
||||||
|
dump::modinfo(std::cout, reader);
|
||||||
|
dump::dynamic_tags(std::cout, reader);
|
||||||
|
dump::section_datas(std::cout, reader);
|
||||||
|
dump::segment_datas(std::cout, reader);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+44
-22
@@ -35,6 +35,7 @@
|
|||||||
#ifndef _RISCV_HART_M_P_HWL_H
|
#ifndef _RISCV_HART_M_P_HWL_H
|
||||||
#define _RISCV_HART_M_P_HWL_H
|
#define _RISCV_HART_M_P_HWL_H
|
||||||
|
|
||||||
|
#include "riscv_hart_common.h"
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
@@ -46,17 +47,17 @@ public:
|
|||||||
using this_class = hwl<BASE>;
|
using this_class = hwl<BASE>;
|
||||||
using reg_t = typename BASE::reg_t;
|
using reg_t = typename BASE::reg_t;
|
||||||
|
|
||||||
hwl();
|
hwl(feature_config cfg = feature_config{});
|
||||||
virtual ~hwl() = default;
|
virtual ~hwl() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
iss::status read_custom_csr_reg(unsigned addr, reg_t &val) override;
|
iss::status read_custom_csr(unsigned addr, reg_t& val) override;
|
||||||
iss::status write_custom_csr_reg(unsigned addr, reg_t val) override;
|
iss::status write_custom_csr(unsigned addr, reg_t val) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
inline hwl<BASE>::hwl() {
|
inline hwl<BASE>::hwl(feature_config cfg)
|
||||||
|
: BASE(cfg) {
|
||||||
for(unsigned addr = 0x800; addr < 0x803; ++addr) {
|
for(unsigned addr = 0x800; addr < 0x803; ++addr) {
|
||||||
this->register_custom_csr_rd(addr);
|
this->register_custom_csr_rd(addr);
|
||||||
this->register_custom_csr_wr(addr);
|
this->register_custom_csr_wr(addr);
|
||||||
@@ -67,28 +68,50 @@ inline hwl<BASE>::hwl() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BASE>
|
template <typename BASE> inline iss::status iss::arch::hwl<BASE>::read_custom_csr(unsigned addr, reg_t& val) {
|
||||||
inline iss::status iss::arch::hwl<BASE>::read_custom_csr_reg(unsigned addr, reg_t &val) {
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x800: val = this->reg.lpstart0; break;
|
case 0x800:
|
||||||
case 0x801: val = this->reg.lpend0; break;
|
val = this->reg.lpstart0;
|
||||||
case 0x802: val = this->reg.lpcount0; break;
|
break;
|
||||||
case 0x804: val = this->reg.lpstart1; break;
|
case 0x801:
|
||||||
case 0x805: val = this->reg.lpend1; break;
|
val = this->reg.lpend0;
|
||||||
case 0x806: val = this->reg.lpcount1; break;
|
break;
|
||||||
|
case 0x802:
|
||||||
|
val = this->reg.lpcount0;
|
||||||
|
break;
|
||||||
|
case 0x804:
|
||||||
|
val = this->reg.lpstart1;
|
||||||
|
break;
|
||||||
|
case 0x805:
|
||||||
|
val = this->reg.lpend1;
|
||||||
|
break;
|
||||||
|
case 0x806:
|
||||||
|
val = this->reg.lpcount1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BASE>
|
template <typename BASE> inline iss::status iss::arch::hwl<BASE>::write_custom_csr(unsigned addr, reg_t val) {
|
||||||
inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg_t val) {
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x800: this->reg.lpstart0 = val; break;
|
case 0x800:
|
||||||
case 0x801: this->reg.lpend0 = val; break;
|
this->reg.lpstart0 = val;
|
||||||
case 0x802: this->reg.lpcount0 = val; break;
|
break;
|
||||||
case 0x804: this->reg.lpstart1 = val; break;
|
case 0x801:
|
||||||
case 0x805: this->reg.lpend1 = val; break;
|
this->reg.lpend0 = val;
|
||||||
case 0x806: this->reg.lpcount1 = val; break;
|
break;
|
||||||
|
case 0x802:
|
||||||
|
this->reg.lpcount0 = val;
|
||||||
|
break;
|
||||||
|
case 0x804:
|
||||||
|
this->reg.lpstart1 = val;
|
||||||
|
break;
|
||||||
|
case 0x805:
|
||||||
|
this->reg.lpend1 = val;
|
||||||
|
break;
|
||||||
|
case 0x806:
|
||||||
|
this->reg.lpcount1 = val;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
@@ -96,5 +119,4 @@ inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg
|
|||||||
} // namespace arch
|
} // namespace arch
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
||||||
|
|
||||||
#endif /* _RISCV_HART_M_P_H */
|
#endif /* _RISCV_HART_M_P_H */
|
||||||
@@ -35,8 +35,23 @@
|
|||||||
#ifndef _RISCV_HART_COMMON
|
#ifndef _RISCV_HART_COMMON
|
||||||
#define _RISCV_HART_COMMON
|
#define _RISCV_HART_COMMON
|
||||||
|
|
||||||
#include "iss/arch_if.h"
|
#include "iss/vm_types.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <elfio/elfio.hpp>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include <iss/arch_if.h>
|
||||||
|
#include <iss/log_categories.h>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <util/logging.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define likely(x) ::__builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) ::__builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define likely(x) x
|
||||||
|
#define unlikely(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
namespace arch {
|
||||||
@@ -175,7 +190,6 @@ enum riscv_csr {
|
|||||||
dscratch1 = 0x7B3
|
dscratch1 = 0x7B3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PGSHIFT = 12,
|
PGSHIFT = 12,
|
||||||
PTE_PPN_SHIFT = 10,
|
PTE_PPN_SHIFT = 10,
|
||||||
@@ -226,6 +240,8 @@ struct feature_config {
|
|||||||
unsigned clic_num_trigger{0};
|
unsigned clic_num_trigger{0};
|
||||||
uint64_t tcm_base{0x10000000};
|
uint64_t tcm_base{0x10000000};
|
||||||
uint64_t tcm_size{0x8000};
|
uint64_t tcm_size{0x8000};
|
||||||
|
uint64_t io_address{0xf0000000};
|
||||||
|
uint64_t io_addr_mask{0xf0000000};
|
||||||
};
|
};
|
||||||
|
|
||||||
class trap_load_access_fault : public trap_access {
|
class trap_load_access_fault : public trap_access {
|
||||||
@@ -295,8 +311,75 @@ inline void write_reg_uint32(uint64_t offs, uint32_t& reg, const uint8_t *const
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
struct riscv_hart_common {
|
||||||
|
riscv_hart_common(){};
|
||||||
|
~riscv_hart_common(){};
|
||||||
|
std::unordered_map<std::string, uint64_t> symbol_table;
|
||||||
|
uint64_t entry_address{0};
|
||||||
|
uint64_t tohost = tohost_dflt;
|
||||||
|
uint64_t fromhost = fromhost_dflt;
|
||||||
|
|
||||||
|
bool read_elf_file(std::string name, uint8_t expected_elf_class,
|
||||||
|
std::function<iss::status(uint64_t, uint64_t, const uint8_t* const)> cb) {
|
||||||
|
// Create elfio reader
|
||||||
|
ELFIO::elfio reader;
|
||||||
|
// Load ELF data
|
||||||
|
if(reader.load(name)) {
|
||||||
|
// check elf properties
|
||||||
|
if(reader.get_class() != expected_elf_class)
|
||||||
|
return false;
|
||||||
|
if(reader.get_type() != ELFIO::ET_EXEC)
|
||||||
|
return false;
|
||||||
|
if(reader.get_machine() != ELFIO::EM_RISCV)
|
||||||
|
return false;
|
||||||
|
entry_address = reader.get_entry();
|
||||||
|
for(const auto& pseg : reader.segments) {
|
||||||
|
const auto fsize = pseg->get_file_size(); // 0x42c/0x0
|
||||||
|
const auto seg_data = pseg->get_data();
|
||||||
|
const auto type = pseg->get_type();
|
||||||
|
if(type == 1 && fsize > 0) {
|
||||||
|
auto res = cb(pseg->get_physical_address(), fsize, reinterpret_cast<const uint8_t* const>(seg_data));
|
||||||
|
if(res != iss::Ok)
|
||||||
|
CPPLOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex << pseg->get_physical_address();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto sym_sec = reader.sections[".symtab"];
|
||||||
|
if(ELFIO::SHT_SYMTAB == sym_sec->get_type() || ELFIO::SHT_DYNSYM == sym_sec->get_type()) {
|
||||||
|
ELFIO::symbol_section_accessor symbols(reader, sym_sec);
|
||||||
|
auto sym_no = symbols.get_symbols_num();
|
||||||
|
std::string name;
|
||||||
|
ELFIO::Elf64_Addr value = 0;
|
||||||
|
ELFIO::Elf_Xword size = 0;
|
||||||
|
unsigned char bind = 0;
|
||||||
|
unsigned char type = 0;
|
||||||
|
ELFIO::Elf_Half section = 0;
|
||||||
|
unsigned char other = 0;
|
||||||
|
for(auto i = 0U; i < sym_no; ++i) {
|
||||||
|
symbols.get_symbol(i, name, value, size, bind, type, section, other);
|
||||||
|
if(name != "") {
|
||||||
|
this->symbol_table[name] = value;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
CPPLOG(DEBUG) << "Found Symbol " << name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
tohost = symbol_table.at("tohost");
|
||||||
|
try {
|
||||||
|
fromhost = symbol_table.at("fromhost");
|
||||||
|
} catch(std::out_of_range& e) {
|
||||||
|
fromhost = tohost + 0x40;
|
||||||
|
}
|
||||||
|
} catch(std::out_of_range& e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace arch
|
||||||
|
} // namespace iss
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+324
-281
File diff suppressed because it is too large.
Load diff
+240
-219
@@ -35,38 +35,34 @@
|
|||||||
#ifndef _RISCV_HART_MSU_VP_H
|
#ifndef _RISCV_HART_MSU_VP_H
|
||||||
#define _RISCV_HART_MSU_VP_H
|
#define _RISCV_HART_MSU_VP_H
|
||||||
|
|
||||||
#include "riscv_hart_common.h"
|
|
||||||
#include "iss/arch/traits.h"
|
#include "iss/arch/traits.h"
|
||||||
#include "iss/instrumentation_if.h"
|
#include "iss/instrumentation_if.h"
|
||||||
#include "iss/log_categories.h"
|
#include "iss/log_categories.h"
|
||||||
#include "iss/vm_if.h"
|
#include "iss/vm_if.h"
|
||||||
|
#include "iss/vm_types.h"
|
||||||
|
#include "riscv_hart_common.h"
|
||||||
|
#include <stdexcept>
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <elfio/elfio.hpp>
|
#include <elfio/elfio.hpp>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <functional>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <functional>
|
|
||||||
#include <util/bit_field.h>
|
#include <util/bit_field.h>
|
||||||
#include <util/ities.h>
|
#include <util/ities.h>
|
||||||
#include <util/sparse_array.h>
|
#include <util/sparse_array.h>
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#include <iss/semihosting/semihosting.h>
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
#else
|
|
||||||
#define likely(x) x
|
|
||||||
#define unlikely(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
namespace arch {
|
||||||
|
|
||||||
template <typename BASE> class riscv_hart_msu_vp : public BASE {
|
template <typename BASE> class riscv_hart_msu_vp : public BASE, public riscv_hart_common {
|
||||||
protected:
|
protected:
|
||||||
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
|
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
|
||||||
const std::array<const char*, 16> trap_str = {{""
|
const std::array<const char*, 16> trap_str = {{""
|
||||||
@@ -86,10 +82,11 @@ protected:
|
|||||||
"Load page fault", // d
|
"Load page fault", // d
|
||||||
"Reserved", // e
|
"Reserved", // e
|
||||||
"Store/AMO page fault"}};
|
"Store/AMO page fault"}};
|
||||||
const std::array<const char *, 12> irq_str = {
|
const std::array<const char*, 12> irq_str = {{"User software interrupt", "Supervisor software interrupt", "Reserved",
|
||||||
{"User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt",
|
"Machine software interrupt", "User timer interrupt", "Supervisor timer interrupt",
|
||||||
"User timer interrupt", "Supervisor timer interrupt", "Reserved", "Machine timer interrupt",
|
"Reserved", "Machine timer interrupt", "User external interrupt",
|
||||||
"User external interrupt", "Supervisor external interrupt", "Reserved", "Machine external interrupt"}};
|
"Supervisor external interrupt", "Reserved", "Machine external interrupt"}};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using core = BASE;
|
using core = BASE;
|
||||||
using this_class = riscv_hart_msu_vp<BASE>;
|
using this_class = riscv_hart_msu_vp<BASE>;
|
||||||
@@ -107,7 +104,8 @@ public:
|
|||||||
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
|
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint32_t>::value>::type> {
|
||||||
public:
|
public:
|
||||||
BEGIN_BF_DECL(mstatus_t, T);
|
BEGIN_BF_DECL(mstatus_t, T);
|
||||||
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
|
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR
|
||||||
|
// XS==11)))
|
||||||
BF_FIELD(SD, 31, 1);
|
BF_FIELD(SD, 31, 1);
|
||||||
// Trap SRET
|
// Trap SRET
|
||||||
BF_FIELD(TSR, 22, 1);
|
BF_FIELD(TSR, 22, 1);
|
||||||
@@ -121,7 +119,8 @@ public:
|
|||||||
BF_FIELD(SUM, 18, 1);
|
BF_FIELD(SUM, 18, 1);
|
||||||
// Modify PRiVilege
|
// Modify PRiVilege
|
||||||
BF_FIELD(MPRV, 17, 1);
|
BF_FIELD(MPRV, 17, 1);
|
||||||
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None dirty, some clean/Some dirty
|
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None
|
||||||
|
// dirty, some clean/Some dirty
|
||||||
BF_FIELD(XS, 15, 2);
|
BF_FIELD(XS, 15, 2);
|
||||||
// floating-point unit status Off/Initial/Clean/Dirty
|
// floating-point unit status Off/Initial/Clean/Dirty
|
||||||
BF_FIELD(FS, 13, 2);
|
BF_FIELD(FS, 13, 2);
|
||||||
@@ -162,20 +161,27 @@ public:
|
|||||||
return priv_lvl == PRIV_U ? 0x80000011UL : priv_lvl == PRIV_S ? 0x800de133UL : 0x807ff9ddUL;
|
return priv_lvl == PRIV_U ? 0x80000011UL : priv_lvl == PRIV_S ? 0x800de133UL : 0x807ff9ddUL;
|
||||||
#else
|
#else
|
||||||
switch(priv_lvl) {
|
switch(priv_lvl) {
|
||||||
case PRIV_U: return 0x80000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001
|
case PRIV_U:
|
||||||
case PRIV_S: return 0x800de133UL; // 0b1000 0000 0000 1101 1110 0001 0011 0011
|
return 0x80000011UL; // 0b1000 0000 0000 0000 0000 0000 0001 0001
|
||||||
default: return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011
|
case PRIV_S:
|
||||||
|
return 0x800de133UL; // 0b1000 0000 0000 1101 1110 0001 0011 0011
|
||||||
|
default:
|
||||||
|
return 0x807ff9ddUL; // 0b1000 0000 0111 1111 1111 1001 1011 1011
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
|
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
|
||||||
if (state == PRIV_M) return {0, 0, 0, 0};
|
if(state == PRIV_M)
|
||||||
|
return {0, 0, 0, 0};
|
||||||
if(state <= PRIV_S)
|
if(state <= PRIV_S)
|
||||||
switch(bit_sub<31, 1>(sptbr)) {
|
switch(bit_sub<31, 1>(sptbr)) {
|
||||||
case 0: return {0, 0, 0, 0}; // off
|
case 0:
|
||||||
case 1: return {2, 10, 4, bit_sub<0, 22>(sptbr) << PGSHIFT}; // SV32
|
return {0, 0, 0, 0}; // off
|
||||||
default: abort();
|
case 1:
|
||||||
|
return {2, 10, 4, bit_sub<0, 22>(sptbr) << PGSHIFT}; // SV32
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
return {0, 0, 0, 0}; // dummy
|
return {0, 0, 0, 0}; // dummy
|
||||||
@@ -185,7 +191,8 @@ public:
|
|||||||
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
|
template <typename T> class hart_state<T, typename std::enable_if<std::is_same<T, uint64_t>::value>::type> {
|
||||||
public:
|
public:
|
||||||
BEGIN_BF_DECL(mstatus_t, T);
|
BEGIN_BF_DECL(mstatus_t, T);
|
||||||
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR XS==11)))
|
// SD bit is read-only and is set when either the FS or XS bits encode a Dirty state (i.e., SD=((FS==11) OR
|
||||||
|
// XS==11)))
|
||||||
BF_FIELD(SD, 63, 1);
|
BF_FIELD(SD, 63, 1);
|
||||||
// value of XLEN for S-mode
|
// value of XLEN for S-mode
|
||||||
BF_FIELD(SXL, 34, 2);
|
BF_FIELD(SXL, 34, 2);
|
||||||
@@ -203,7 +210,8 @@ public:
|
|||||||
BF_FIELD(SUM, 18, 1);
|
BF_FIELD(SUM, 18, 1);
|
||||||
// Modify PRiVilege
|
// Modify PRiVilege
|
||||||
BF_FIELD(MPRV, 17, 1);
|
BF_FIELD(MPRV, 17, 1);
|
||||||
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None dirty, some clean/Some dirty
|
// status of additional user-mode extensions and associated state, All off/None dirty or clean, some on/None
|
||||||
|
// dirty, some clean/Some dirty
|
||||||
BF_FIELD(XS, 15, 2);
|
BF_FIELD(XS, 15, 2);
|
||||||
// floating-point unit status Off/Initial/Clean/Dirty
|
// floating-point unit status Off/Initial/Clean/Dirty
|
||||||
BF_FIELD(FS, 13, 2);
|
BF_FIELD(FS, 13, 2);
|
||||||
@@ -249,23 +257,36 @@ public:
|
|||||||
static constexpr T get_mask(unsigned priv_lvl) {
|
static constexpr T get_mask(unsigned priv_lvl) {
|
||||||
uint64_t ret;
|
uint64_t ret;
|
||||||
switch(priv_lvl) {
|
switch(priv_lvl) {
|
||||||
case PRIV_U: ret = 0x8000000f00000011ULL;break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
case PRIV_U:
|
||||||
case PRIV_S: ret = 0x8000000f000de133ULL;break; // 0b1...0 0011 0000 0000 0000 1101 1110 0001 0011 0011
|
ret = 0x8000000f00000011ULL;
|
||||||
default: ret = 0x8000000f007ff9ddULL;break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
||||||
|
case PRIV_S:
|
||||||
|
ret = 0x8000000f000de133ULL;
|
||||||
|
break; // 0b1...0 0011 0000 0000 0000 1101 1110 0001 0011 0011
|
||||||
|
default:
|
||||||
|
ret = 0x8000000f007ff9ddULL;
|
||||||
|
break; // 0b1...0 1111 0000 0000 0111 1111 1111 1001 1011 1011
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
|
static inline vm_info decode_vm_info(uint32_t state, T sptbr) {
|
||||||
if (state == PRIV_M) return {0, 0, 0, 0};
|
if(state == PRIV_M)
|
||||||
|
return {0, 0, 0, 0};
|
||||||
if(state <= PRIV_S)
|
if(state <= PRIV_S)
|
||||||
switch(bit_sub<60, 4>(sptbr)) {
|
switch(bit_sub<60, 4>(sptbr)) {
|
||||||
case 0: return {0, 0, 0, 0}; // off
|
case 0:
|
||||||
case 8: return {3, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV39
|
return {0, 0, 0, 0}; // off
|
||||||
case 9: return {4, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV48
|
case 8:
|
||||||
case 10: return {5, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV57
|
return {3, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT}; // SV39
|
||||||
case 11: return {6, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT};// SV64
|
case 9:
|
||||||
default: abort();
|
return {4, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT}; // SV48
|
||||||
|
case 10:
|
||||||
|
return {5, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT}; // SV57
|
||||||
|
case 11:
|
||||||
|
return {6, 9, 8, bit_sub<0, 44>(sptbr) << PGSHIFT}; // SV64
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
abort();
|
abort();
|
||||||
return {0, 0, 0, 0}; // dummy
|
return {0, 0, 0, 0}; // dummy
|
||||||
@@ -286,7 +307,7 @@ public:
|
|||||||
return m[mode];
|
return m[mode];
|
||||||
}
|
}
|
||||||
|
|
||||||
riscv_hart_msu_vp();
|
riscv_hart_msu_vp(feature_config cfg = feature_config{});
|
||||||
virtual ~riscv_hart_msu_vp() = default;
|
virtual ~riscv_hart_msu_vp() = default;
|
||||||
|
|
||||||
void reset(uint64_t address) override;
|
void reset(uint64_t address) override;
|
||||||
@@ -295,10 +316,10 @@ public:
|
|||||||
|
|
||||||
phys_addr_t virt2phys(const iss::addr_t& addr) override;
|
phys_addr_t virt2phys(const iss::addr_t& addr) override;
|
||||||
|
|
||||||
iss::status read(const address_type type, const access_type access, const uint32_t space,
|
iss::status read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length,
|
||||||
const uint64_t addr, const unsigned length, uint8_t *const data) override;
|
uint8_t* const data) override;
|
||||||
iss::status write(const address_type type, const access_type access, const uint32_t space,
|
iss::status write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length,
|
||||||
const uint64_t addr, const unsigned length, const uint8_t *const data) override;
|
const uint8_t* const data) override;
|
||||||
|
|
||||||
uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data, fault_data); }
|
uint64_t enter_trap(uint64_t flags) override { return riscv_hart_msu_vp::enter_trap(flags, fault_data, fault_data); }
|
||||||
uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override;
|
uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override;
|
||||||
@@ -306,19 +327,18 @@ public:
|
|||||||
void wait_until(uint64_t flags) override;
|
void wait_until(uint64_t flags) override;
|
||||||
|
|
||||||
void disass_output(uint64_t pc, const std::string instr) override {
|
void disass_output(uint64_t pc, const std::string instr) override {
|
||||||
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]",
|
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus,
|
||||||
pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus, this->reg.icount + cycle_offset);
|
this->reg.cycle + cycle_offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
iss::instrumentation_if* get_instrumentation_if() override { return &instr_if; }
|
iss::instrumentation_if* get_instrumentation_if() override { return &instr_if; }
|
||||||
|
|
||||||
void set_csr(unsigned addr, reg_t val){
|
void set_csr(unsigned addr, reg_t val) { csr[addr & csr.page_addr_mask] = val; }
|
||||||
csr[addr & csr.page_addr_mask] = val;
|
|
||||||
}
|
void set_irq_num(unsigned i) { mcause_max_irq = 1 << util::ilog2(i); }
|
||||||
|
|
||||||
|
void set_semihosting_callback(std::function<void(arch_if*, reg_t, reg_t)>& cb) { semihosting_cb = cb; };
|
||||||
|
|
||||||
void set_irq_num(unsigned i) {
|
|
||||||
mcause_max_irq=1<<util::ilog2(i);
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
struct riscv_instrumentation_if : public iss::instrumentation_if {
|
struct riscv_instrumentation_if : public iss::instrumentation_if {
|
||||||
|
|
||||||
@@ -331,9 +351,9 @@ protected:
|
|||||||
*/
|
*/
|
||||||
const std::string core_type_name() const override { return traits<BASE>::core_type; }
|
const std::string core_type_name() const override { return traits<BASE>::core_type; }
|
||||||
|
|
||||||
uint64_t get_pc() override { return arch.reg.PC; };
|
uint64_t get_pc() override { return arch.reg.PC; }
|
||||||
|
|
||||||
uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
|
uint64_t get_next_pc() override { return arch.reg.NEXT_PC; }
|
||||||
|
|
||||||
uint64_t get_instr_word() override { return arch.reg.instruction; }
|
uint64_t get_instr_word() override { return arch.reg.instruction; }
|
||||||
|
|
||||||
@@ -341,11 +361,17 @@ protected:
|
|||||||
|
|
||||||
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
|
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
|
||||||
|
|
||||||
uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
|
uint64_t get_total_cycles() override { return arch.reg.cycle + arch.cycle_offset; }
|
||||||
|
|
||||||
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
|
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; }
|
||||||
|
|
||||||
bool is_branch_taken() override { return arch.reg.last_branch; };
|
bool is_branch_taken() override { return arch.reg.last_branch; }
|
||||||
|
|
||||||
|
unsigned get_reg_num() override { return traits<BASE>::NUM_REGS; }
|
||||||
|
|
||||||
|
unsigned get_reg_size(unsigned num) override { return traits<BASE>::reg_bit_widths[num]; }
|
||||||
|
|
||||||
|
std::unordered_map<std::string, uint64_t> const& get_symbol_table(std::string name) override { return arch.symbol_table; }
|
||||||
|
|
||||||
riscv_hart_msu_vp<BASE>& arch;
|
riscv_hart_msu_vp<BASE>& arch;
|
||||||
};
|
};
|
||||||
@@ -367,11 +393,11 @@ protected:
|
|||||||
uint64_t minstret_csr{0};
|
uint64_t minstret_csr{0};
|
||||||
reg_t fault_data;
|
reg_t fault_data;
|
||||||
std::array<vm_info, 2> vm;
|
std::array<vm_info, 2> vm;
|
||||||
uint64_t tohost = tohost_dflt;
|
bool tohost_lower_written = false;
|
||||||
uint64_t fromhost = fromhost_dflt;
|
|
||||||
unsigned to_host_wr_cnt = 0;
|
|
||||||
riscv_instrumentation_if instr_if;
|
riscv_instrumentation_if instr_if;
|
||||||
|
|
||||||
|
std::function<void(arch_if*, reg_t, reg_t)> semihosting_cb;
|
||||||
|
|
||||||
using mem_type = util::sparse_array<uint8_t, 1ULL << 32>;
|
using mem_type = util::sparse_array<uint8_t, 1ULL << 32>;
|
||||||
using csr_type = util::sparse_array<typename traits<BASE>::reg_t, 1ULL << 12, 12>;
|
using csr_type = util::sparse_array<typename traits<BASE>::reg_t, 1ULL << 12, 12>;
|
||||||
using csr_page_type = typename csr_type::page_type;
|
using csr_page_type = typename csr_type::page_type;
|
||||||
@@ -414,12 +440,8 @@ protected:
|
|||||||
virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; };
|
virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; };
|
||||||
virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; };
|
virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; };
|
||||||
|
|
||||||
void register_custom_csr_rd(unsigned addr){
|
void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr_reg; }
|
||||||
csr_rd_cb[addr] = &this_class::read_custom_csr_reg;
|
void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr_reg; }
|
||||||
}
|
|
||||||
void register_custom_csr_wr(unsigned addr){
|
|
||||||
csr_wr_cb[addr] = &this_class::write_custom_csr_reg;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t mhartid_reg{0x0};
|
reg_t mhartid_reg{0x0};
|
||||||
|
|
||||||
@@ -458,32 +480,36 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
|||||||
// csr_wr_cb[addr] = &this_class::write_csr_reg;
|
// csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
// common regs
|
// common regs
|
||||||
const std::array<unsigned, 22> addrs{{
|
const std::array<unsigned, 22> addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause,
|
||||||
misa, mvendorid, marchid, mimpid,
|
mtval, mscratch, sepc, stvec, sscratch, scause, stval, sscratch,
|
||||||
mepc, mtvec, mscratch, mcause, mtval, mscratch,
|
uepc, utvec, uscratch, ucause, utval, uscratch}};
|
||||||
sepc, stvec, sscratch, scause, stval, sscratch,
|
|
||||||
uepc, utvec, uscratch, ucause, utval, uscratch
|
|
||||||
}};
|
|
||||||
for(auto addr : addrs) {
|
for(auto addr : addrs) {
|
||||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||||
}
|
}
|
||||||
// special handling & overrides
|
// special handling & overrides
|
||||||
csr_rd_cb[time] = &this_class::read_time;
|
csr_rd_cb[time] = &this_class::read_time;
|
||||||
if(traits<BASE>::XLEN==32) csr_rd_cb[timeh] = &this_class::read_time;
|
if(traits<BASE>::XLEN == 32)
|
||||||
|
csr_rd_cb[timeh] = &this_class::read_time;
|
||||||
csr_rd_cb[cycle] = &this_class::read_cycle;
|
csr_rd_cb[cycle] = &this_class::read_cycle;
|
||||||
if(traits<BASE>::XLEN==32) csr_rd_cb[cycleh] = &this_class::read_cycle;
|
if(traits<BASE>::XLEN == 32)
|
||||||
|
csr_rd_cb[cycleh] = &this_class::read_cycle;
|
||||||
csr_rd_cb[instret] = &this_class::read_instret;
|
csr_rd_cb[instret] = &this_class::read_instret;
|
||||||
if(traits<BASE>::XLEN==32) csr_rd_cb[instreth] = &this_class::read_instret;
|
if(traits<BASE>::XLEN == 32)
|
||||||
|
csr_rd_cb[instreth] = &this_class::read_instret;
|
||||||
|
|
||||||
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
csr_rd_cb[mcycle] = &this_class::read_cycle;
|
||||||
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
csr_wr_cb[mcycle] = &this_class::write_cycle;
|
||||||
if(traits<BASE>::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
if(traits<BASE>::XLEN == 32)
|
||||||
if(traits<BASE>::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
csr_rd_cb[mcycleh] = &this_class::read_cycle;
|
||||||
|
if(traits<BASE>::XLEN == 32)
|
||||||
|
csr_wr_cb[mcycleh] = &this_class::write_cycle;
|
||||||
csr_rd_cb[minstret] = &this_class::read_instret;
|
csr_rd_cb[minstret] = &this_class::read_instret;
|
||||||
csr_wr_cb[minstret] = &this_class::write_instret;
|
csr_wr_cb[minstret] = &this_class::write_instret;
|
||||||
if(traits<BASE>::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret;
|
if(traits<BASE>::XLEN == 32)
|
||||||
if(traits<BASE>::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret;
|
csr_rd_cb[minstreth] = &this_class::read_instret;
|
||||||
|
if(traits<BASE>::XLEN == 32)
|
||||||
|
csr_wr_cb[minstreth] = &this_class::write_instret;
|
||||||
csr_rd_cb[mstatus] = &this_class::read_status;
|
csr_rd_cb[mstatus] = &this_class::read_status;
|
||||||
csr_wr_cb[mstatus] = &this_class::write_status;
|
csr_wr_cb[mstatus] = &this_class::write_status;
|
||||||
csr_wr_cb[mcause] = &this_class::write_cause;
|
csr_wr_cb[mcause] = &this_class::write_cause;
|
||||||
@@ -529,81 +555,26 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
|
template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) {
|
||||||
FILE *fp = fopen(name.c_str(), "r");
|
if(read_elf_file(name, sizeof(reg_t) == 4 ? ELFIO::ELFCLASS32 : ELFIO::ELFCLASS64,
|
||||||
if (fp) {
|
[this](uint64_t addr, uint64_t size, const uint8_t* const data) -> iss::status {
|
||||||
std::array<char, 5> buf;
|
return this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE, traits<BASE>::MEM, addr, size,
|
||||||
auto n = fread(buf.data(), 1, 4, fp);
|
data);
|
||||||
fclose(fp);
|
})) {
|
||||||
if (n != 4) throw std::runtime_error("input file has insufficient size");
|
return std::make_pair(entry_address, true);
|
||||||
buf[4] = 0;
|
|
||||||
if (strcmp(buf.data() + 1, "ELF") == 0) {
|
|
||||||
// Create elfio reader
|
|
||||||
ELFIO::elfio reader;
|
|
||||||
// Load ELF data
|
|
||||||
if (!reader.load(name)) throw std::runtime_error("could not process elf file");
|
|
||||||
// check elf properties
|
|
||||||
if (reader.get_class() != ELFCLASS32)
|
|
||||||
if (sizeof(reg_t) == 4) throw std::runtime_error("wrong elf class in file");
|
|
||||||
if (reader.get_type() != ET_EXEC) throw std::runtime_error("wrong elf type in file");
|
|
||||||
if (reader.get_machine() != EM_RISCV) throw std::runtime_error("wrong elf machine in file");
|
|
||||||
auto entry = reader.get_entry();
|
|
||||||
for (const auto pseg : reader.segments) {
|
|
||||||
const auto fsize = pseg->get_file_size(); // 0x42c/0x0
|
|
||||||
const auto seg_data = pseg->get_data();
|
|
||||||
if (fsize > 0) {
|
|
||||||
auto res = this->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_WRITE,
|
|
||||||
traits<BASE>::MEM, pseg->get_physical_address(),
|
|
||||||
fsize, reinterpret_cast<const uint8_t *const>(seg_data));
|
|
||||||
if (res != iss::Ok)
|
|
||||||
LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex
|
|
||||||
<< pseg->get_physical_address();
|
|
||||||
}
|
}
|
||||||
}
|
return std::make_pair(entry_address, false);
|
||||||
for(const auto sec : reader.sections) {
|
|
||||||
if(sec->get_name() == ".symtab") {
|
|
||||||
if ( SHT_SYMTAB == sec->get_type() ||
|
|
||||||
SHT_DYNSYM == sec->get_type() ) {
|
|
||||||
ELFIO::symbol_section_accessor symbols( reader, sec );
|
|
||||||
auto sym_no = symbols.get_symbols_num();
|
|
||||||
std::string name;
|
|
||||||
ELFIO::Elf64_Addr value = 0;
|
|
||||||
ELFIO::Elf_Xword size = 0;
|
|
||||||
unsigned char bind = 0;
|
|
||||||
unsigned char type = 0;
|
|
||||||
ELFIO::Elf_Half section = 0;
|
|
||||||
unsigned char other = 0;
|
|
||||||
for ( auto i = 0U; i < sym_no; ++i ) {
|
|
||||||
symbols.get_symbol( i, name, value, size, bind, type, section, other );
|
|
||||||
if(name=="tohost") {
|
|
||||||
tohost = value;
|
|
||||||
} else if(name=="fromhost") {
|
|
||||||
fromhost = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (sec->get_name() == ".tohost") {
|
|
||||||
tohost = sec->get_address();
|
|
||||||
fromhost = tohost + 0x40;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return std::make_pair(entry, true);
|
|
||||||
}
|
|
||||||
throw std::runtime_error(fmt::format("memory load file {} is not a valid elf file",name));
|
|
||||||
}
|
|
||||||
throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_type access, const uint32_t space,
|
iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr,
|
||||||
const uint64_t addr, const unsigned length, uint8_t *const data) {
|
const unsigned length, uint8_t* const data) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if(access && iss::access_type::DEBUG) {
|
if(access && iss::access_type::DEBUG) {
|
||||||
LOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
|
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
|
||||||
} else if(access && iss::access_type::FETCH) {
|
} else if(access && iss::access_type::FETCH) {
|
||||||
LOG(TRACEALL) << "fetch of " << length << " bytes @addr 0x" << std::hex << addr;
|
CPPLOG(TRACEALL) << "fetch of " << length << " bytes @addr 0x" << std::hex << addr;
|
||||||
} else {
|
} else {
|
||||||
LOG(TRACE) << "read of " << length << " bytes @addr 0x" << std::hex << addr;
|
CPPLOG(TRACE) << "read of " << length << " bytes @addr 0x" << std::hex << addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
try {
|
try {
|
||||||
@@ -612,7 +583,8 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
|||||||
auto alignment = is_fetch(access) ? (traits<BASE>::MISA_VAL & 0x100 ? 2 : 4) : length;
|
auto alignment = is_fetch(access) ? (traits<BASE>::MISA_VAL & 0x100 ? 2 : 4) : length;
|
||||||
if(unlikely(is_fetch(access) && (addr & (alignment - 1)))) {
|
if(unlikely(is_fetch(access) && (addr & (alignment - 1)))) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if(access && iss::access_type::DEBUG)
|
||||||
|
throw trap_access(0, addr);
|
||||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
@@ -634,23 +606,27 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto res = read_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data);
|
auto res = read_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data);
|
||||||
if (unlikely(res != iss::Ok)){
|
if(unlikely(res != iss::Ok && (access & access_type::DEBUG) == 0)) {
|
||||||
this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
|
this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
this->reg.trap_state = (1 << 31) | ta.id;
|
if((access & access_type::DEBUG) == 0) {
|
||||||
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
fault_data = ta.addr;
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::CSR: {
|
case traits<BASE>::CSR: {
|
||||||
if (length != sizeof(reg_t)) return iss::Err;
|
if(length != sizeof(reg_t))
|
||||||
|
return iss::Err;
|
||||||
return read_csr(addr, *reinterpret_cast<reg_t* const>(data));
|
return read_csr(addr, *reinterpret_cast<reg_t* const>(data));
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::FENCE: {
|
case traits<BASE>::FENCE: {
|
||||||
if ((addr + length) > mem.size()) return iss::Err;
|
if((addr + length) > mem.size())
|
||||||
|
return iss::Err;
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 2: // SFENCE:VMA lower
|
case 2: // SFENCE:VMA lower
|
||||||
case 3: { // SFENCE:VMA upper
|
case 3: { // SFENCE:VMA upper
|
||||||
@@ -677,36 +653,38 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
|
|||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
|
if((access & access_type::DEBUG) == 0) {
|
||||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
fault_data = ta.addr;
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access_type access, const uint32_t space,
|
iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr,
|
||||||
const uint64_t addr, const unsigned length, const uint8_t *const data) {
|
const unsigned length, const uint8_t* const data) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
|
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
|
||||||
switch(length) {
|
switch(length) {
|
||||||
case 8:
|
case 8:
|
||||||
LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec
|
CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t*)&data[0] << std::dec << ") @addr 0x"
|
||||||
<< ") @addr 0x" << std::hex << addr;
|
<< std::hex << addr;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t *)&data[0] << std::dec
|
CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint32_t*)&data[0] << std::dec << ") @addr 0x"
|
||||||
<< ") @addr 0x" << std::hex << addr;
|
<< std::hex << addr;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t *)&data[0] << std::dec
|
CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint16_t*)&data[0] << std::dec << ") @addr 0x"
|
||||||
<< ") @addr 0x" << std::hex << addr;
|
<< std::hex << addr;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
LOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec
|
CPPLOG(TRACE) << prefix << "write of " << length << " bytes (0x" << std::hex << (uint16_t)data[0] << std::dec << ") @addr 0x"
|
||||||
<< ") @addr 0x" << std::hex << addr;
|
<< std::hex << addr;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
|
CPPLOG(TRACE) << prefix << "write of " << length << " bytes @addr " << addr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
try {
|
try {
|
||||||
@@ -714,7 +692,8 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
case traits<BASE>::MEM: {
|
case traits<BASE>::MEM: {
|
||||||
if(unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
|
if(unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
|
if(access && iss::access_type::DEBUG)
|
||||||
|
throw trap_access(0, addr);
|
||||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
@@ -732,7 +711,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto res = write_mem(paddr, length, data);
|
auto res = write_mem(paddr, length, data);
|
||||||
if (unlikely(res != iss::Ok)) {
|
if(unlikely(res != iss::Ok && (access & access_type::DEBUG) == 0)) {
|
||||||
this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
|
this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
|
||||||
fault_data = addr;
|
fault_data = addr;
|
||||||
}
|
}
|
||||||
@@ -743,13 +722,14 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((paddr.val + length) > mem.size()) return iss::Err;
|
if((paddr.val + length) > mem.size())
|
||||||
|
return iss::Err;
|
||||||
switch(paddr.val) {
|
switch(paddr.val) {
|
||||||
case 0x10013000: // UART0 base, TXFIFO reg
|
case 0x10013000: // UART0 base, TXFIFO reg
|
||||||
case 0x10023000: // UART1 base, TXFIFO reg
|
case 0x10023000: // UART1 base, TXFIFO reg
|
||||||
uart_buf << (char)data[0];
|
uart_buf << (char)data[0];
|
||||||
if(((char)data[0]) == '\n' || data[0] == 0) {
|
if(((char)data[0]) == '\n' || data[0] == 0) {
|
||||||
// LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
|
// CPPLOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
|
||||||
// '"<<uart_buf.str()<<"'";
|
// '"<<uart_buf.str()<<"'";
|
||||||
std::cout << uart_buf.str();
|
std::cout << uart_buf.str();
|
||||||
uart_buf.str("");
|
uart_buf.str("");
|
||||||
@@ -760,7 +740,8 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
auto offs = paddr.val & mem.page_addr_mask;
|
auto offs = paddr.val & mem.page_addr_mask;
|
||||||
std::copy(data, data + length, p.data() + offs);
|
std::copy(data, data + length, p.data() + offs);
|
||||||
auto& x = *(p.data() + offs + 3);
|
auto& x = *(p.data() + offs + 3);
|
||||||
if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1
|
if(x & 0x40)
|
||||||
|
x |= 0x80; // hfroscrdy = 1 if hfroscen==1
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
case 0x10008008: { // HFROSC base, pllcfg reg
|
case 0x10008008: { // HFROSC base, pllcfg reg
|
||||||
@@ -771,15 +752,18 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
x |= 0x80; // set pll lock upon writing
|
x |= 0x80; // set pll lock upon writing
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} break;
|
} break;
|
||||||
default: {}
|
default: {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::CSR: {
|
case traits<BASE>::CSR: {
|
||||||
if (length != sizeof(reg_t)) return iss::Err;
|
if(length != sizeof(reg_t))
|
||||||
|
return iss::Err;
|
||||||
return write_csr(addr, *reinterpret_cast<const reg_t*>(data));
|
return write_csr(addr, *reinterpret_cast<const reg_t*>(data));
|
||||||
} break;
|
} break;
|
||||||
case traits<BASE>::FENCE: {
|
case traits<BASE>::FENCE: {
|
||||||
if ((addr + length) > mem.size()) return iss::Err;
|
if((addr + length) > mem.size())
|
||||||
|
return iss::Err;
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 2:
|
case 2:
|
||||||
case 3: {
|
case 3: {
|
||||||
@@ -802,14 +786,17 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
|
|||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
|
if((access & access_type::DEBUG) == 0) {
|
||||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
fault_data = ta.addr;
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_csr(unsigned addr, reg_t& val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_csr(unsigned addr, reg_t& val) {
|
||||||
if (addr >= csr.size()) return iss::Err;
|
if(addr >= csr.size())
|
||||||
|
return iss::Err;
|
||||||
auto req_priv_lvl = (addr >> 8) & 0x3;
|
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||||
if(this->reg.PRIV < req_priv_lvl) // not having required privileges
|
if(this->reg.PRIV < req_priv_lvl) // not having required privileges
|
||||||
throw illegal_instruction_fault(this->fault_data);
|
throw illegal_instruction_fault(this->fault_data);
|
||||||
@@ -820,7 +807,8 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_csr(unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_csr(unsigned addr, reg_t val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_csr(unsigned addr, reg_t val) {
|
||||||
if (addr >= csr.size()) return iss::Err;
|
if(addr >= csr.size())
|
||||||
|
return iss::Err;
|
||||||
auto req_priv_lvl = (addr >> 8) & 0x3;
|
auto req_priv_lvl = (addr >> 8) & 0x3;
|
||||||
if(this->reg.PRIV < req_priv_lvl) // not having required privileges
|
if(this->reg.PRIV < req_priv_lvl) // not having required privileges
|
||||||
throw illegal_instruction_fault(this->fault_data);
|
throw illegal_instruction_fault(this->fault_data);
|
||||||
@@ -848,11 +836,12 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_reg(unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t& val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigned addr, reg_t& val) {
|
||||||
auto cycle_val = this->reg.icount + cycle_offset;
|
auto cycle_val = this->reg.cycle + cycle_offset;
|
||||||
if(addr == mcycle) {
|
if(addr == mcycle) {
|
||||||
val = static_cast<reg_t>(cycle_val);
|
val = static_cast<reg_t>(cycle_val);
|
||||||
} else if(addr == mcycleh) {
|
} else if(addr == mcycleh) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
if(sizeof(typename traits<BASE>::reg_t) != 4)
|
||||||
|
return iss::Err;
|
||||||
val = static_cast<reg_t>(cycle_val >> 32);
|
val = static_cast<reg_t>(cycle_val >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
@@ -868,7 +857,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cycle(unsign
|
|||||||
mcycle_csr = (static_cast<uint64_t>(val) << 32) + (mcycle_csr & 0xffffffff);
|
mcycle_csr = (static_cast<uint64_t>(val) << 32) + (mcycle_csr & 0xffffffff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around
|
cycle_offset = mcycle_csr - this->reg.cycle; // TODO: relying on wrap-around
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -896,11 +885,12 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_instret(unsi
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t& val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_time(unsigned addr, reg_t& val) {
|
||||||
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
|
uint64_t time_val = this->reg.cycle / (100000000 / 32768 - 1); //-> ~3052;
|
||||||
if(addr == time) {
|
if(addr == time) {
|
||||||
val = static_cast<reg_t>(time_val);
|
val = static_cast<reg_t>(time_val);
|
||||||
} else if(addr == timeh) {
|
} else if(addr == timeh) {
|
||||||
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
|
if(sizeof(typename traits<BASE>::reg_t) != 4)
|
||||||
|
return iss::Err;
|
||||||
val = static_cast<reg_t>(time_val >> 32);
|
val = static_cast<reg_t>(time_val >> 32);
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
@@ -932,8 +922,10 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cause(unsign
|
|||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ie(unsigned addr, reg_t& val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ie(unsigned addr, reg_t& val) {
|
||||||
val = csr[mie];
|
val = csr[mie];
|
||||||
if (addr < mie) val &= csr[mideleg];
|
if(addr < mie)
|
||||||
if (addr < sie) val &= csr[sideleg];
|
val &= csr[mideleg];
|
||||||
|
if(addr < sie)
|
||||||
|
val &= csr[sideleg];
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -952,8 +944,10 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ie(unsigned
|
|||||||
|
|
||||||
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ip(unsigned addr, reg_t& val) {
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_ip(unsigned addr, reg_t& val) {
|
||||||
val = csr[mip];
|
val = csr[mip];
|
||||||
if (addr < mip) val &= csr[mideleg];
|
if(addr < mip)
|
||||||
if (addr < sip) val &= csr[sideleg];
|
val &= csr[mideleg];
|
||||||
|
if(addr < sip)
|
||||||
|
val &= csr[sideleg];
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,8 +1012,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigne
|
|||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t* const data) {
|
||||||
iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
|
|
||||||
switch(paddr.val) {
|
switch(paddr.val) {
|
||||||
default: {
|
default: {
|
||||||
for(auto offs = 0U; offs < length; ++offs) {
|
for(auto offs = 0U; offs < length; ++offs) {
|
||||||
@@ -1030,12 +1023,11 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
|
|||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t* const data) {
|
||||||
iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
|
|
||||||
switch(paddr.val) {
|
switch(paddr.val) {
|
||||||
case 0xFFFF0000: // UART0 base, TXFIFO reg
|
case 0xFFFF0000: // UART0 base, TXFIFO reg
|
||||||
if(((char)data[0]) == '\n' || data[0] == 0) {
|
if(((char)data[0]) == '\n' || data[0] == 0) {
|
||||||
LOG(INFO)<<"UART"<<((paddr.val>>12)&0x3)<<" send '"<<uart_buf.str()<<"'";
|
CPPLOG(INFO) << "UART" << ((paddr.val >> 12) & 0x3) << " send '" << uart_buf.str() << "'";
|
||||||
uart_buf.str("");
|
uart_buf.str("");
|
||||||
} else if(((char)data[0]) != '\r')
|
} else if(((char)data[0]) != '\r')
|
||||||
uart_buf << (char)data[0];
|
uart_buf << (char)data[0];
|
||||||
@@ -1045,42 +1037,43 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
|||||||
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
||||||
// tohost handling in case of riscv-test
|
// tohost handling in case of riscv-test
|
||||||
if(paddr.access && iss::access_type::FUNC) {
|
if(paddr.access && iss::access_type::FUNC) {
|
||||||
auto tohost_upper = (traits<BASE>::XLEN == 32 && paddr.val == (tohost + 4)) ||
|
auto tohost_upper =
|
||||||
(traits<BASE>::XLEN == 64 && paddr.val == tohost);
|
(traits<BASE>::XLEN == 32 && paddr.val == (tohost + 4)) || (traits<BASE>::XLEN == 64 && paddr.val == tohost);
|
||||||
auto tohost_lower =
|
auto tohost_lower = (traits<BASE>::XLEN == 32 && paddr.val == tohost) || (traits<BASE>::XLEN == 64 && paddr.val == tohost);
|
||||||
(traits<BASE>::XLEN == 32 && paddr.val == tohost) || (traits<BASE>::XLEN == 64 && paddr.val == tohost);
|
|
||||||
if(tohost_lower || tohost_upper) {
|
if(tohost_lower || tohost_upper) {
|
||||||
uint64_t hostvar = *reinterpret_cast<uint64_t*>(p.data() + (tohost & mem.page_addr_mask));
|
uint64_t hostvar = *reinterpret_cast<uint64_t*>(p.data() + (tohost & mem.page_addr_mask));
|
||||||
if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) {
|
// in case of 32 bit system, two writes to tohost are needed, only evaluate on the second (high) write
|
||||||
|
if(tohost_upper && (tohost_lower || tohost_lower_written)) {
|
||||||
switch(hostvar >> 48) {
|
switch(hostvar >> 48) {
|
||||||
case 0:
|
case 0:
|
||||||
if(hostvar != 0x1) {
|
if(hostvar != 0x1) {
|
||||||
LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
CPPLOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||||
<< "), stopping simulation";
|
<< "), stopping simulation";
|
||||||
} else {
|
} else {
|
||||||
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
CPPLOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
|
||||||
<< "), stopping simulation";
|
<< "), stopping simulation";
|
||||||
}
|
}
|
||||||
this->reg.trap_state = std::numeric_limits<uint32_t>::max();
|
this->reg.trap_state = std::numeric_limits<uint32_t>::max();
|
||||||
this->interrupt_sim = hostvar;
|
this->interrupt_sim = hostvar;
|
||||||
|
#ifndef WITH_TCC
|
||||||
|
throw(iss::simulation_stopped(hostvar));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
//throw(iss::simulation_stopped(hostvar));
|
|
||||||
case 0x0101: {
|
case 0x0101: {
|
||||||
char c = static_cast<char>(hostvar & 0xff);
|
char c = static_cast<char>(hostvar & 0xff);
|
||||||
if(c == '\n' || c == 0) {
|
if(c == '\n' || c == 0) {
|
||||||
LOG(INFO) << "tohost send '" << uart_buf.str() << "'";
|
CPPLOG(INFO) << "tohost send '" << uart_buf.str() << "'";
|
||||||
uart_buf.str("");
|
uart_buf.str("");
|
||||||
} else
|
} else
|
||||||
uart_buf << c;
|
uart_buf << c;
|
||||||
to_host_wr_cnt = 0;
|
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
tohost_lower_written = false;
|
||||||
} else if(tohost_lower)
|
} else if(tohost_lower)
|
||||||
to_host_wr_cnt++;
|
tohost_lower_written = true;
|
||||||
} else if ((traits<BASE>::XLEN == 32 && paddr.val == fromhost + 4) ||
|
} else if((traits<BASE>::XLEN == 32 && paddr.val == fromhost + 4) || (traits<BASE>::XLEN == 64 && paddr.val == fromhost)) {
|
||||||
(traits<BASE>::XLEN == 64 && paddr.val == fromhost)) {
|
|
||||||
uint64_t fhostvar = *reinterpret_cast<uint64_t*>(p.data() + (fromhost & mem.page_addr_mask));
|
uint64_t fhostvar = *reinterpret_cast<uint64_t*>(p.data() + (fromhost & mem.page_addr_mask));
|
||||||
*reinterpret_cast<uint64_t*>(p.data() + (tohost & mem.page_addr_mask)) = fhostvar;
|
*reinterpret_cast<uint64_t*>(p.data() + (tohost & mem.page_addr_mask)) = fhostvar;
|
||||||
}
|
}
|
||||||
@@ -1129,13 +1122,13 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
|||||||
}
|
}
|
||||||
if(enabled_interrupts != 0) {
|
if(enabled_interrupts != 0) {
|
||||||
int res = 0;
|
int res = 0;
|
||||||
while ((enabled_interrupts & 1) == 0) enabled_interrupts >>= 1, res++;
|
while((enabled_interrupts & 1) == 0)
|
||||||
|
enabled_interrupts >>= 1, res++;
|
||||||
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE> typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys(const iss::addr_t& addr) {
|
||||||
typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys(const iss::addr_t &addr) {
|
|
||||||
const auto type = addr.access & iss::access_type::FUNC;
|
const auto type = addr.access & iss::access_type::FUNC;
|
||||||
auto it = ptw.find(addr.val >> PGSHIFT);
|
auto it = ptw.find(addr.val >> PGSHIFT);
|
||||||
if(it != ptw.end()) {
|
if(it != ptw.end()) {
|
||||||
@@ -1154,8 +1147,8 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV
|
uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV
|
||||||
state.mstatus.MPP :
|
state.mstatus.MPP
|
||||||
this->reg.PRIV;
|
: this->reg.PRIV;
|
||||||
|
|
||||||
const vm_info& vm = this->vm[static_cast<uint16_t>(type) / 2];
|
const vm_info& vm = this->vm[static_cast<uint16_t>(type) / 2];
|
||||||
|
|
||||||
@@ -1176,9 +1169,10 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
|
|||||||
|
|
||||||
// check that physical address of PTE is legal
|
// check that physical address of PTE is legal
|
||||||
reg_t pte = 0;
|
reg_t pte = 0;
|
||||||
const uint8_t res = this->read(iss::address_type::PHYSICAL, addr.access,
|
const uint8_t res = this->read(iss::address_type::PHYSICAL, addr.access, traits<BASE>::MEM, base + idx * vm.ptesize, vm.ptesize,
|
||||||
traits<BASE>::MEM, base + idx * vm.ptesize, vm.ptesize, (uint8_t *)&pte);
|
(uint8_t*)&pte);
|
||||||
if (res != 0) throw trap_load_access_fault(addr.val);
|
if(res != 0)
|
||||||
|
throw trap_load_access_fault(addr.val);
|
||||||
const reg_t ppn = pte >> PTE_PPN_SHIFT;
|
const reg_t ppn = pte >> PTE_PPN_SHIFT;
|
||||||
|
|
||||||
if(PTE_TABLE(pte)) { // next level of page table
|
if(PTE_TABLE(pte)) { // next level of page table
|
||||||
@@ -1187,10 +1181,9 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
|
|||||||
break;
|
break;
|
||||||
} else if(!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
|
} else if(!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
|
||||||
break;
|
break;
|
||||||
} else if (type == iss::access_type::FETCH
|
} else if(type == (iss::access_type::FETCH ? !(pte & PTE_X)
|
||||||
? !(pte & PTE_X)
|
|
||||||
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
||||||
: !((pte & PTE_R) && (pte & PTE_W))) {
|
: !((pte & PTE_R) && (pte & PTE_W)))) {
|
||||||
break;
|
break;
|
||||||
} else if((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
|
} else if((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
|
||||||
break;
|
break;
|
||||||
@@ -1201,7 +1194,8 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys
|
|||||||
*(uint32_t*)ppte |= ad;
|
*(uint32_t*)ppte |= ad;
|
||||||
#else
|
#else
|
||||||
// take exception if access or possibly dirty bit is not set.
|
// take exception if access or possibly dirty bit is not set.
|
||||||
if ((pte & ad) != ad) break;
|
if((pte & ad) != ad)
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
// for superpage mappings, make a fake leaf PTE for the TLB's benefit.
|
// for superpage mappings, make a fake leaf PTE for the TLB's benefit.
|
||||||
const reg_t vpn = addr.val >> PGSHIFT;
|
const reg_t vpn = addr.val >> PGSHIFT;
|
||||||
@@ -1231,10 +1225,12 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
|||||||
auto cur_priv = this->reg.PRIV;
|
auto cur_priv = this->reg.PRIV;
|
||||||
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
|
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
|
||||||
// calculate and write mcause val
|
// calculate and write mcause val
|
||||||
if(flags==std::numeric_limits<uint64_t>::max()) flags=this->reg.trap_state;
|
if(flags == std::numeric_limits<uint64_t>::max())
|
||||||
|
flags = this->reg.trap_state;
|
||||||
auto trap_id = bit_sub<0, 16>(flags);
|
auto trap_id = bit_sub<0, 16>(flags);
|
||||||
auto cause = bit_sub<16, 15>(flags);
|
auto cause = bit_sub<16, 15>(flags);
|
||||||
if (trap_id == 0 && cause == 11) cause = 0x8 + cur_priv; // adjust environment call cause
|
if(trap_id == 0 && cause == 11)
|
||||||
|
cause = 0x8 + cur_priv; // adjust environment call cause
|
||||||
// calculate effective privilege level
|
// calculate effective privilege level
|
||||||
auto new_priv = PRIV_M;
|
auto new_priv = PRIV_M;
|
||||||
if(trap_id == 0) { // exception
|
if(trap_id == 0) { // exception
|
||||||
@@ -1261,6 +1257,31 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
|||||||
// csr[dpc] = addr;
|
// csr[dpc] = addr;
|
||||||
// csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi)
|
// csr[dcsr] = (csr[dcsr] & ~0x1c3) | (1<<6) | PRIV_M; //FIXME: cause should not be 4 (stepi)
|
||||||
csr[utval | (new_priv << 8)] = addr;
|
csr[utval | (new_priv << 8)] = addr;
|
||||||
|
if(semihosting_cb) {
|
||||||
|
// Check for semihosting call
|
||||||
|
phys_addr_t p_addr(access_type::DEBUG_READ, traits<BASE>::MEM, addr - 4);
|
||||||
|
std::array<uint8_t, 8> data;
|
||||||
|
// check for SLLI_X0_X0_0X1F and SRAI_X0_X0_0X07
|
||||||
|
this->read_mem(p_addr, 4, data.data());
|
||||||
|
p_addr.val += 8;
|
||||||
|
this->read_mem(p_addr, 4, data.data() + 4);
|
||||||
|
|
||||||
|
const std::array<uint8_t, 8> ref_data = {0x13, 0x10, 0xf0, 0x01, 0x13, 0x50, 0x70, 0x40};
|
||||||
|
if(data == ref_data) {
|
||||||
|
this->reg.NEXT_PC = addr + 8;
|
||||||
|
|
||||||
|
std::array<char, 32> buffer;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
sprintf(buffer.data(), "0x%016llx", addr);
|
||||||
|
#else
|
||||||
|
sprintf(buffer.data(), "0x%016lx", addr);
|
||||||
|
#endif
|
||||||
|
CLOG(INFO, disass) << "Semihosting call at address " << buffer.data() << " occurred ";
|
||||||
|
|
||||||
|
semihosting_callback(this, this->reg.X10 /*a0*/, this->reg.X11 /*a1*/);
|
||||||
|
return this->reg.NEXT_PC;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
case 6:
|
case 6:
|
||||||
@@ -1278,7 +1299,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
|||||||
this->reg.pending_trap = 0;
|
this->reg.pending_trap = 0;
|
||||||
}
|
}
|
||||||
size_t adr = ucause | (new_priv << 8);
|
size_t adr = ucause | (new_priv << 8);
|
||||||
csr[adr] = (trap_id << 31) + cause;
|
csr[adr] = (trap_id << (traits<BASE>::XLEN - 1)) + cause;
|
||||||
// update mstatus
|
// update mstatus
|
||||||
// xPP field of mstatus is written with the active privilege mode at the time
|
// xPP field of mstatus is written with the active privilege mode at the time
|
||||||
// of the trap; the x PIE field of mstatus
|
// of the trap; the x PIE field of mstatus
|
||||||
@@ -1310,14 +1331,15 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
|||||||
// calculate addr// set NEXT_PC to trap addressess to jump to based on MODE
|
// calculate addr// set NEXT_PC to trap addressess to jump to based on MODE
|
||||||
// bits in mtvec
|
// bits in mtvec
|
||||||
this->reg.NEXT_PC = ivec & ~0x3UL;
|
this->reg.NEXT_PC = ivec & ~0x3UL;
|
||||||
if ((ivec & 0x1) == 1 && trap_id != 0) this->reg.NEXT_PC += 4 * cause;
|
if((ivec & 0x1) == 1 && trap_id != 0)
|
||||||
|
this->reg.NEXT_PC += 4 * cause;
|
||||||
std::array<char, 32> buffer;
|
std::array<char, 32> buffer;
|
||||||
sprintf(buffer.data(), "0x%016lx", addr);
|
sprintf(buffer.data(), "0x%016lx", addr);
|
||||||
if((flags & 0xffffffff) != 0xffffffff)
|
if((flags & 0xffffffff) != 0xffffffff)
|
||||||
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '"
|
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' ("
|
||||||
<< (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" << cause << ")"
|
<< cause << ")"
|
||||||
<< " at address " << buffer.data() << " occurred, changing privilege level from "
|
<< " at address " << buffer.data() << " occurred, changing privilege level from " << lvl[cur_priv] << " to "
|
||||||
<< lvl[cur_priv] << " to " << lvl[new_priv];
|
<< lvl[new_priv];
|
||||||
// reset trap state
|
// reset trap state
|
||||||
this->reg.PRIV = new_priv;
|
this->reg.PRIV = new_priv;
|
||||||
this->reg.trap_state = 0;
|
this->reg.trap_state = 0;
|
||||||
@@ -1360,8 +1382,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f
|
|||||||
}
|
}
|
||||||
// sets the pc to the value stored in the x epc register.
|
// sets the pc to the value stored in the x epc register.
|
||||||
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
|
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
|
||||||
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to "
|
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " << lvl[this->reg.PRIV];
|
||||||
<< lvl[this->reg.PRIV];
|
|
||||||
update_vm_info();
|
update_vm_info();
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
return this->reg.NEXT_PC;
|
return this->reg.NEXT_PC;
|
||||||
@@ -1375,7 +1396,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags
|
|||||||
this->fault_data = this->reg.PC;
|
this->fault_data = this->reg.PC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} // namespace arch
|
||||||
}
|
} // namespace iss
|
||||||
|
|
||||||
#endif /* _RISCV_HART_MSU_VP_H */
|
#endif /* _RISCV_HART_MSU_VP_H */
|
||||||
+358
-304
File diff suppressed because it is too large.
Load diff
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017 - 2020 MINRES Technologies GmbH
|
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
#include "tgc5c.h"
|
#include "tgc5c.h"
|
||||||
#include "util/ities.h"
|
#include "util/ities.h"
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
@@ -66,4 +67,4 @@ uint8_t *tgc5c::get_regs_base_ptr() {
|
|||||||
tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t &addr) {
|
tgc5c::phys_addr_t tgc5c::virt2phys(const iss::addr_t &addr) {
|
||||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<tgc5c>::addr_mask);
|
return phys_addr_t(addr.access, addr.space, addr.val&traits<tgc5c>::addr_mask);
|
||||||
}
|
}
|
||||||
|
// clang-format on
|
||||||
+36
-35
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (C) 2017 - 2021 MINRES Technologies GmbH
|
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#ifndef _TGC5C_H_
|
#ifndef _TGC5C_H_
|
||||||
#define _TGC5C_H_
|
#define _TGC5C_H_
|
||||||
|
// clang-format off
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
@@ -48,12 +48,12 @@ template <> struct traits<tgc5c> {
|
|||||||
constexpr static char const* const core_type = "TGC5C";
|
constexpr static char const* const core_type = "TGC5C";
|
||||||
|
|
||||||
static constexpr std::array<const char*, 36> reg_names{
|
static constexpr std::array<const char*, 36> reg_names{
|
||||||
{"X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "X10", "X11", "X12", "X13", "X14", "X15", "X16", "X17", "X18", "X19", "X20", "X21", "X22", "X23", "X24", "X25", "X26", "X27", "X28", "X29", "X30", "X31", "PC", "NEXT_PC", "PRIV", "DPC"}};
|
{"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31", "pc", "next_pc", "priv", "dpc"}};
|
||||||
|
|
||||||
static constexpr std::array<const char*, 36> reg_aliases{
|
static constexpr std::array<const char*, 36> reg_aliases{
|
||||||
{"ZERO", "RA", "SP", "GP", "TP", "T0", "T1", "T2", "S0", "S1", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "S11", "T3", "T4", "T5", "T6", "PC", "NEXT_PC", "PRIV", "DPC"}};
|
{"zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", "pc", "next_pc", "priv", "dpc"}};
|
||||||
|
|
||||||
enum constants {MISA_VAL=1073746180ULL, MARCHID_VAL=2147483651ULL, XLEN=32ULL, INSTR_ALIGNMENT=2ULL, RFS=32ULL, fence=0ULL, fencei=1ULL, fencevmal=2ULL, fencevmau=3ULL, CSR_SIZE=4096ULL, MUL_LEN=64ULL};
|
enum constants {MISA_VAL=1073746180ULL, MARCHID_VAL=2147483651ULL, CLIC_NUM_IRQ=0ULL, XLEN=32ULL, FLEN=0ULL, INSTR_ALIGNMENT=2ULL, RFS=32ULL, fence=0ULL, fencei=1ULL, fencevmal=2ULL, fencevmau=3ULL, RV_CSR_FFLAGS=1ULL, RV_CSR_FRM=2ULL, RV_CSR_FCSR=3ULL, RV_CSR_UTVT=7ULL, RV_CSR_VSTART=8ULL, RV_CSR_VXSAT=9ULL, RV_CSR_VXRM=10ULL, RV_CSR_VCSR=15ULL, RV_CSR_SEED=21ULL, RV_CSR_UNXTI=69ULL, RV_CSR_UINTSTATUS=70ULL, RV_CSR_USCRATCHCSW=72ULL, RV_CSR_USCRATCHCSWL=73ULL, RV_CSR_SSTATUS=256ULL, RV_CSR_SEDELEG=258ULL, RV_CSR_SIDELEG=259ULL, RV_CSR_SIE=260ULL, RV_CSR_STVEC=261ULL, RV_CSR_SCOUNTEREN=262ULL, RV_CSR_STVT=263ULL, RV_CSR_SENVCFG=266ULL, RV_CSR_SSTATEEN0=268ULL, RV_CSR_SSTATEEN1=269ULL, RV_CSR_SSTATEEN2=270ULL, RV_CSR_SSTATEEN3=271ULL, RV_CSR_SSCRATCH=320ULL, RV_CSR_SEPC=321ULL, RV_CSR_SCAUSE=322ULL, RV_CSR_STVAL=323ULL, RV_CSR_SIP=324ULL, RV_CSR_SNXTI=325ULL, RV_CSR_SINTSTATUS=326ULL, RV_CSR_SSCRATCHCSW=328ULL, RV_CSR_SSCRATCHCSWL=329ULL, RV_CSR_STIMECMP=333ULL, RV_CSR_STIMECMPH=349ULL, RV_CSR_SATP=384ULL, RV_CSR_VSSTATUS=512ULL, RV_CSR_VSIE=516ULL, RV_CSR_VSTVEC=517ULL, RV_CSR_VSSCRATCH=576ULL, RV_CSR_VSEPC=577ULL, RV_CSR_VSCAUSE=578ULL, RV_CSR_VSTVAL=579ULL, RV_CSR_VSIP=580ULL, RV_CSR_VSTIMECMP=589ULL, RV_CSR_VSTIMECMPH=605ULL, RV_CSR_VSATP=640ULL, RV_CSR_MSTATUS=768ULL, RV_CSR_MISA=769ULL, RV_CSR_MEDELEG=770ULL, RV_CSR_MIDELEG=771ULL, RV_CSR_MIE=772ULL, RV_CSR_MTVEC=773ULL, RV_CSR_MCOUNTEREN=774ULL, RV_CSR_MTVT=775ULL, RV_CSR_MENVCFG=778ULL, RV_CSR_MSTATEEN0=780ULL, RV_CSR_MSTATEEN1=781ULL, RV_CSR_MSTATEEN2=782ULL, RV_CSR_MSTATEEN3=783ULL, RV_CSR_MSTATUSH=784ULL, RV_CSR_MENVCFGH=794ULL, RV_CSR_MSTATEEN0H=796ULL, RV_CSR_MSTATEEN1H=797ULL, RV_CSR_MSTATEEN2H=798ULL, RV_CSR_MSTATEEN3H=799ULL, RV_CSR_MCOUNTINHIBIT=800ULL, RV_CSR_MHPMEVENT3=803ULL, RV_CSR_MHPMEVENT4=804ULL, RV_CSR_MHPMEVENT5=805ULL, RV_CSR_MHPMEVENT6=806ULL, RV_CSR_MHPMEVENT7=807ULL, RV_CSR_MHPMEVENT8=808ULL, RV_CSR_MHPMEVENT9=809ULL, RV_CSR_MHPMEVENT10=810ULL, RV_CSR_MHPMEVENT11=811ULL, RV_CSR_MHPMEVENT12=812ULL, RV_CSR_MHPMEVENT13=813ULL, RV_CSR_MHPMEVENT14=814ULL, RV_CSR_MHPMEVENT15=815ULL, RV_CSR_MHPMEVENT16=816ULL, RV_CSR_MHPMEVENT17=817ULL, RV_CSR_MHPMEVENT18=818ULL, RV_CSR_MHPMEVENT19=819ULL, RV_CSR_MHPMEVENT20=820ULL, RV_CSR_MHPMEVENT21=821ULL, RV_CSR_MHPMEVENT22=822ULL, RV_CSR_MHPMEVENT23=823ULL, RV_CSR_MHPMEVENT24=824ULL, RV_CSR_MHPMEVENT25=825ULL, RV_CSR_MHPMEVENT26=826ULL, RV_CSR_MHPMEVENT27=827ULL, RV_CSR_MHPMEVENT28=828ULL, RV_CSR_MHPMEVENT29=829ULL, RV_CSR_MHPMEVENT30=830ULL, RV_CSR_MHPMEVENT31=831ULL, RV_CSR_MSCRATCH=832ULL, RV_CSR_MEPC=833ULL, RV_CSR_MCAUSE=834ULL, RV_CSR_MTVAL=835ULL, RV_CSR_MIP=836ULL, RV_CSR_MNXTI=837ULL, RV_CSR_MINTSTATUS=838ULL, RV_CSR_MSCRATCHCSW=840ULL, RV_CSR_MSCRATCHCSWL=841ULL, RV_CSR_MTINST=842ULL, RV_CSR_MTVAL2=843ULL, RV_CSR_PMPCFG0=928ULL, RV_CSR_PMPCFG1=929ULL, RV_CSR_PMPCFG2=930ULL, RV_CSR_PMPCFG3=931ULL, RV_CSR_PMPCFG4=932ULL, RV_CSR_PMPCFG5=933ULL, RV_CSR_PMPCFG6=934ULL, RV_CSR_PMPCFG7=935ULL, RV_CSR_PMPCFG8=936ULL, RV_CSR_PMPCFG9=937ULL, RV_CSR_PMPCFG10=938ULL, RV_CSR_PMPCFG11=939ULL, RV_CSR_PMPCFG12=940ULL, RV_CSR_PMPCFG13=941ULL, RV_CSR_PMPCFG14=942ULL, RV_CSR_PMPCFG15=943ULL, RV_CSR_PMPADDR0=944ULL, RV_CSR_PMPADDR1=945ULL, RV_CSR_PMPADDR2=946ULL, RV_CSR_PMPADDR3=947ULL, RV_CSR_PMPADDR4=948ULL, RV_CSR_PMPADDR5=949ULL, RV_CSR_PMPADDR6=950ULL, RV_CSR_PMPADDR7=951ULL, RV_CSR_PMPADDR8=952ULL, RV_CSR_PMPADDR9=953ULL, RV_CSR_PMPADDR10=954ULL, RV_CSR_PMPADDR11=955ULL, RV_CSR_PMPADDR12=956ULL, RV_CSR_PMPADDR13=957ULL, RV_CSR_PMPADDR14=958ULL, RV_CSR_PMPADDR15=959ULL, RV_CSR_PMPADDR16=960ULL, RV_CSR_PMPADDR17=961ULL, RV_CSR_PMPADDR18=962ULL, RV_CSR_PMPADDR19=963ULL, RV_CSR_PMPADDR20=964ULL, RV_CSR_PMPADDR21=965ULL, RV_CSR_PMPADDR22=966ULL, RV_CSR_PMPADDR23=967ULL, RV_CSR_PMPADDR24=968ULL, RV_CSR_PMPADDR25=969ULL, RV_CSR_PMPADDR26=970ULL, RV_CSR_PMPADDR27=971ULL, RV_CSR_PMPADDR28=972ULL, RV_CSR_PMPADDR29=973ULL, RV_CSR_PMPADDR30=974ULL, RV_CSR_PMPADDR31=975ULL, RV_CSR_PMPADDR32=976ULL, RV_CSR_PMPADDR33=977ULL, RV_CSR_PMPADDR34=978ULL, RV_CSR_PMPADDR35=979ULL, RV_CSR_PMPADDR36=980ULL, RV_CSR_PMPADDR37=981ULL, RV_CSR_PMPADDR38=982ULL, RV_CSR_PMPADDR39=983ULL, RV_CSR_PMPADDR40=984ULL, RV_CSR_PMPADDR41=985ULL, RV_CSR_PMPADDR42=986ULL, RV_CSR_PMPADDR43=987ULL, RV_CSR_PMPADDR44=988ULL, RV_CSR_PMPADDR45=989ULL, RV_CSR_PMPADDR46=990ULL, RV_CSR_PMPADDR47=991ULL, RV_CSR_PMPADDR48=992ULL, RV_CSR_PMPADDR49=993ULL, RV_CSR_PMPADDR50=994ULL, RV_CSR_PMPADDR51=995ULL, RV_CSR_PMPADDR52=996ULL, RV_CSR_PMPADDR53=997ULL, RV_CSR_PMPADDR54=998ULL, RV_CSR_PMPADDR55=999ULL, RV_CSR_PMPADDR56=1000ULL, RV_CSR_PMPADDR57=1001ULL, RV_CSR_PMPADDR58=1002ULL, RV_CSR_PMPADDR59=1003ULL, RV_CSR_PMPADDR60=1004ULL, RV_CSR_PMPADDR61=1005ULL, RV_CSR_PMPADDR62=1006ULL, RV_CSR_PMPADDR63=1007ULL, RV_CSR_SCONTEXT=1448ULL, RV_CSR_HSTATUS=1536ULL, RV_CSR_HEDELEG=1538ULL, RV_CSR_HIDELEG=1539ULL, RV_CSR_HIE=1540ULL, RV_CSR_HTIMEDELTA=1541ULL, RV_CSR_HCOUNTEREN=1542ULL, RV_CSR_HGEIE=1543ULL, RV_CSR_HENVCFG=1546ULL, RV_CSR_HSTATEEN0=1548ULL, RV_Line truncated
|
||||||
|
|
||||||
constexpr static unsigned FP_REGS_SIZE = 0;
|
constexpr static unsigned FP_REGS_SIZE = 0;
|
||||||
|
|
||||||
@@ -81,7 +81,7 @@ template <> struct traits<tgc5c> {
|
|||||||
|
|
||||||
enum sreg_flag_e { FLAGS };
|
enum sreg_flag_e { FLAGS };
|
||||||
|
|
||||||
enum mem_type_e { MEM, FENCE, RES, CSR };
|
enum mem_type_e { MEM, FENCE, RES, CSR, IMEM = MEM };
|
||||||
|
|
||||||
enum class opcode_e {
|
enum class opcode_e {
|
||||||
LUI = 0,
|
LUI = 0,
|
||||||
@@ -141,35 +141,35 @@ template <> struct traits<tgc5c> {
|
|||||||
DIVU = 54,
|
DIVU = 54,
|
||||||
REM = 55,
|
REM = 55,
|
||||||
REMU = 56,
|
REMU = 56,
|
||||||
CADDI4SPN = 57,
|
C__ADDI4SPN = 57,
|
||||||
CLW = 58,
|
C__LW = 58,
|
||||||
CSW = 59,
|
C__SW = 59,
|
||||||
CADDI = 60,
|
C__ADDI = 60,
|
||||||
CNOP = 61,
|
C__NOP = 61,
|
||||||
CJAL = 62,
|
C__JAL = 62,
|
||||||
CLI = 63,
|
C__LI = 63,
|
||||||
CLUI = 64,
|
C__LUI = 64,
|
||||||
CADDI16SP = 65,
|
C__ADDI16SP = 65,
|
||||||
__reserved_clui = 66,
|
__reserved_clui = 66,
|
||||||
CSRLI = 67,
|
C__SRLI = 67,
|
||||||
CSRAI = 68,
|
C__SRAI = 68,
|
||||||
CANDI = 69,
|
C__ANDI = 69,
|
||||||
CSUB = 70,
|
C__SUB = 70,
|
||||||
CXOR = 71,
|
C__XOR = 71,
|
||||||
COR = 72,
|
C__OR = 72,
|
||||||
CAND = 73,
|
C__AND = 73,
|
||||||
CJ = 74,
|
C__J = 74,
|
||||||
CBEQZ = 75,
|
C__BEQZ = 75,
|
||||||
CBNEZ = 76,
|
C__BNEZ = 76,
|
||||||
CSLLI = 77,
|
C__SLLI = 77,
|
||||||
CLWSP = 78,
|
C__LWSP = 78,
|
||||||
CMV = 79,
|
C__MV = 79,
|
||||||
CJR = 80,
|
C__JR = 80,
|
||||||
__reserved_cmv = 81,
|
__reserved_cmv = 81,
|
||||||
CADD = 82,
|
C__ADD = 82,
|
||||||
CJALR = 83,
|
C__JALR = 83,
|
||||||
CEBREAK = 84,
|
C__EBREAK = 84,
|
||||||
CSWSP = 85,
|
C__SWSP = 85,
|
||||||
DII = 86,
|
DII = 86,
|
||||||
MAX_OPCODE
|
MAX_OPCODE
|
||||||
};
|
};
|
||||||
@@ -189,7 +189,7 @@ struct tgc5c: public arch_if {
|
|||||||
|
|
||||||
uint8_t* get_regs_base_ptr() override;
|
uint8_t* get_regs_base_ptr() override;
|
||||||
|
|
||||||
inline uint64_t get_icount() { return reg.icount; }
|
inline uint64_t get_icount() { return reg.icount; } //This should not be accessible, only through the instrumentation_if
|
||||||
|
|
||||||
inline bool should_stop() { return interrupt_sim; }
|
inline bool should_stop() { return interrupt_sim; }
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ struct tgc5c: public arch_if {
|
|||||||
|
|
||||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||||
|
|
||||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
inline uint32_t get_last_branch() { return reg.last_branch; } //This should also only be accessible through the instrumentation_if
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@@ -260,3 +260,4 @@ struct tgc5c: public arch_if {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* _TGC5C_H_ */
|
#endif /* _TGC5C_H_ */
|
||||||
|
// clang-format on
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
#include "tgc_c.h"
|
|
||||||
#include <vector>
|
|
||||||
#include <array>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace iss {
|
|
||||||
namespace arch {
|
|
||||||
namespace {
|
|
||||||
// according to
|
|
||||||
// https://stackoverflow.com/questions/8871204/count-number-of-1s-in-binary-representation
|
|
||||||
#ifdef __GCC__
|
|
||||||
constexpr size_t bit_count(uint32_t u) { return __builtin_popcount(u); }
|
|
||||||
#elif __cplusplus < 201402L
|
|
||||||
constexpr size_t uCount(uint32_t u) { return u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111); }
|
|
||||||
constexpr size_t bit_count(uint32_t u) { return ((uCount(u) + (uCount(u) >> 3)) & 030707070707) % 63; }
|
|
||||||
#else
|
|
||||||
constexpr size_t bit_count(uint32_t u) {
|
|
||||||
size_t uCount = u - ((u >> 1) & 033333333333) - ((u >> 2) & 011111111111);
|
|
||||||
return ((uCount + (uCount >> 3)) & 030707070707) % 63;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using opcode_e = traits<tgc_c>::opcode_e;
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* start opcode definitions
|
|
||||||
****************************************************************************/
|
|
||||||
struct instruction_desriptor {
|
|
||||||
size_t length;
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t mask;
|
|
||||||
opcode_e op;
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::array<instruction_desriptor, 90> instr_descr = {{
|
|
||||||
/* entries are: size, valid value, valid mask, function ptr */
|
|
||||||
{32, 0b00000000000000000000000000110111, 0b00000000000000000000000001111111, opcode_e::LUI},
|
|
||||||
{32, 0b00000000000000000000000000010111, 0b00000000000000000000000001111111, opcode_e::AUIPC},
|
|
||||||
{32, 0b00000000000000000000000001101111, 0b00000000000000000000000001111111, opcode_e::JAL},
|
|
||||||
{32, 0b00000000000000000000000001100111, 0b00000000000000000111000001111111, opcode_e::JALR},
|
|
||||||
{32, 0b00000000000000000000000001100011, 0b00000000000000000111000001111111, opcode_e::BEQ},
|
|
||||||
{32, 0b00000000000000000001000001100011, 0b00000000000000000111000001111111, opcode_e::BNE},
|
|
||||||
{32, 0b00000000000000000100000001100011, 0b00000000000000000111000001111111, opcode_e::BLT},
|
|
||||||
{32, 0b00000000000000000101000001100011, 0b00000000000000000111000001111111, opcode_e::BGE},
|
|
||||||
{32, 0b00000000000000000110000001100011, 0b00000000000000000111000001111111, opcode_e::BLTU},
|
|
||||||
{32, 0b00000000000000000111000001100011, 0b00000000000000000111000001111111, opcode_e::BGEU},
|
|
||||||
{32, 0b00000000000000000000000000000011, 0b00000000000000000111000001111111, opcode_e::LB},
|
|
||||||
{32, 0b00000000000000000001000000000011, 0b00000000000000000111000001111111, opcode_e::LH},
|
|
||||||
{32, 0b00000000000000000010000000000011, 0b00000000000000000111000001111111, opcode_e::LW},
|
|
||||||
{32, 0b00000000000000000100000000000011, 0b00000000000000000111000001111111, opcode_e::LBU},
|
|
||||||
{32, 0b00000000000000000101000000000011, 0b00000000000000000111000001111111, opcode_e::LHU},
|
|
||||||
{32, 0b00000000000000000000000000100011, 0b00000000000000000111000001111111, opcode_e::SB},
|
|
||||||
{32, 0b00000000000000000001000000100011, 0b00000000000000000111000001111111, opcode_e::SH},
|
|
||||||
{32, 0b00000000000000000010000000100011, 0b00000000000000000111000001111111, opcode_e::SW},
|
|
||||||
{32, 0b00000000000000000000000000010011, 0b00000000000000000111000001111111, opcode_e::ADDI},
|
|
||||||
{32, 0b00000000000000000010000000010011, 0b00000000000000000111000001111111, opcode_e::SLTI},
|
|
||||||
{32, 0b00000000000000000011000000010011, 0b00000000000000000111000001111111, opcode_e::SLTIU},
|
|
||||||
{32, 0b00000000000000000100000000010011, 0b00000000000000000111000001111111, opcode_e::XORI},
|
|
||||||
{32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, opcode_e::ORI},
|
|
||||||
{32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, opcode_e::ANDI},
|
|
||||||
{32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, opcode_e::SLLI},
|
|
||||||
{32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRLI},
|
|
||||||
{32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, opcode_e::SRAI},
|
|
||||||
{32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::ADD},
|
|
||||||
{32, 0b01000000000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::SUB},
|
|
||||||
{32, 0b00000000000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::SLL},
|
|
||||||
{32, 0b00000000000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::SLT},
|
|
||||||
{32, 0b00000000000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::SLTU},
|
|
||||||
{32, 0b00000000000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::XOR},
|
|
||||||
{32, 0b00000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRL},
|
|
||||||
{32, 0b01000000000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::SRA},
|
|
||||||
{32, 0b00000000000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::OR},
|
|
||||||
{32, 0b00000000000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::AND},
|
|
||||||
{32, 0b00000000000000000000000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE},
|
|
||||||
{32, 0b00000000000000000000000001110011, 0b11111111111111111111111111111111, opcode_e::ECALL},
|
|
||||||
{32, 0b00000000000100000000000001110011, 0b11111111111111111111111111111111, opcode_e::EBREAK},
|
|
||||||
{32, 0b00000000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::URET},
|
|
||||||
{32, 0b00010000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::SRET},
|
|
||||||
{32, 0b00110000001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::MRET},
|
|
||||||
{32, 0b00010000010100000000000001110011, 0b11111111111111111111111111111111, opcode_e::WFI},
|
|
||||||
{32, 0b01111011001000000000000001110011, 0b11111111111111111111111111111111, opcode_e::DRET},
|
|
||||||
{32, 0b00000000000000000001000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRW},
|
|
||||||
{32, 0b00000000000000000010000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRS},
|
|
||||||
{32, 0b00000000000000000011000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRC},
|
|
||||||
{32, 0b00000000000000000101000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRWI},
|
|
||||||
{32, 0b00000000000000000110000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRSI},
|
|
||||||
{32, 0b00000000000000000111000001110011, 0b00000000000000000111000001111111, opcode_e::CSRRCI},
|
|
||||||
{32, 0b00000000000000000001000000001111, 0b00000000000000000111000001111111, opcode_e::FENCE_I},
|
|
||||||
{32, 0b00000010000000000000000000110011, 0b11111110000000000111000001111111, opcode_e::MUL},
|
|
||||||
{32, 0b00000010000000000001000000110011, 0b11111110000000000111000001111111, opcode_e::MULH},
|
|
||||||
{32, 0b00000010000000000010000000110011, 0b11111110000000000111000001111111, opcode_e::MULHSU},
|
|
||||||
{32, 0b00000010000000000011000000110011, 0b11111110000000000111000001111111, opcode_e::MULHU},
|
|
||||||
{32, 0b00000010000000000100000000110011, 0b11111110000000000111000001111111, opcode_e::DIV},
|
|
||||||
{32, 0b00000010000000000101000000110011, 0b11111110000000000111000001111111, opcode_e::DIVU},
|
|
||||||
{32, 0b00000010000000000110000000110011, 0b11111110000000000111000001111111, opcode_e::REM},
|
|
||||||
{32, 0b00000010000000000111000000110011, 0b11111110000000000111000001111111, opcode_e::REMU},
|
|
||||||
{16, 0b0000000000000000, 0b1110000000000011, opcode_e::CADDI4SPN},
|
|
||||||
{16, 0b0100000000000000, 0b1110000000000011, opcode_e::CLW},
|
|
||||||
{16, 0b1100000000000000, 0b1110000000000011, opcode_e::CSW},
|
|
||||||
{16, 0b0000000000000001, 0b1110000000000011, opcode_e::CADDI},
|
|
||||||
{16, 0b0000000000000001, 0b1110111110000011, opcode_e::CNOP},
|
|
||||||
{16, 0b0010000000000001, 0b1110000000000011, opcode_e::CJAL},
|
|
||||||
{16, 0b0100000000000001, 0b1110000000000011, opcode_e::CLI},
|
|
||||||
{16, 0b0110000000000001, 0b1110000000000011, opcode_e::CLUI},
|
|
||||||
{16, 0b0110000100000001, 0b1110111110000011, opcode_e::CADDI16SP},
|
|
||||||
{16, 0b0110000000000001, 0b1111000001111111, opcode_e::__reserved_clui},
|
|
||||||
{16, 0b1000000000000001, 0b1111110000000011, opcode_e::CSRLI},
|
|
||||||
{16, 0b1000010000000001, 0b1111110000000011, opcode_e::CSRAI},
|
|
||||||
{16, 0b1000100000000001, 0b1110110000000011, opcode_e::CANDI},
|
|
||||||
{16, 0b1000110000000001, 0b1111110001100011, opcode_e::CSUB},
|
|
||||||
{16, 0b1000110000100001, 0b1111110001100011, opcode_e::CXOR},
|
|
||||||
{16, 0b1000110001000001, 0b1111110001100011, opcode_e::COR},
|
|
||||||
{16, 0b1000110001100001, 0b1111110001100011, opcode_e::CAND},
|
|
||||||
{16, 0b1010000000000001, 0b1110000000000011, opcode_e::CJ},
|
|
||||||
{16, 0b1100000000000001, 0b1110000000000011, opcode_e::CBEQZ},
|
|
||||||
{16, 0b1110000000000001, 0b1110000000000011, opcode_e::CBNEZ},
|
|
||||||
{16, 0b0000000000000010, 0b1111000000000011, opcode_e::CSLLI},
|
|
||||||
{16, 0b0100000000000010, 0b1110000000000011, opcode_e::CLWSP},
|
|
||||||
{16, 0b1000000000000010, 0b1111000000000011, opcode_e::CMV},
|
|
||||||
{16, 0b1000000000000010, 0b1111000001111111, opcode_e::CJR},
|
|
||||||
{16, 0b1000000000000010, 0b1111111111111111, opcode_e::__reserved_cmv},
|
|
||||||
{16, 0b1001000000000010, 0b1111000000000011, opcode_e::CADD},
|
|
||||||
{16, 0b1001000000000010, 0b1111000001111111, opcode_e::CJALR},
|
|
||||||
{16, 0b1001000000000010, 0b1111111111111111, opcode_e::CEBREAK},
|
|
||||||
{16, 0b1100000000000010, 0b1110000000000011, opcode_e::CSWSP},
|
|
||||||
{16, 0b0000000000000000, 0b1111111111111111, opcode_e::DII},
|
|
||||||
}};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct instruction_decoder<tgc_c> {
|
|
||||||
using opcode_e = traits<tgc_c>::opcode_e;
|
|
||||||
using code_word_t=traits<tgc_c>::code_word_t;
|
|
||||||
|
|
||||||
struct instruction_pattern {
|
|
||||||
uint32_t value;
|
|
||||||
uint32_t mask;
|
|
||||||
opcode_e id;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::array<std::vector<instruction_pattern>, 4> qlut;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
unsigned decode_instruction(T);
|
|
||||||
|
|
||||||
instruction_decoder() {
|
|
||||||
for (auto instr : instr_descr) {
|
|
||||||
auto quadrant = instr.value & 0x3;
|
|
||||||
qlut[quadrant].push_back(instruction_pattern{instr.value, instr.mask, instr.op});
|
|
||||||
}
|
|
||||||
for(auto& lut: qlut){
|
|
||||||
std::sort(std::begin(lut), std::end(lut), [](instruction_pattern const& a, instruction_pattern const& b){
|
|
||||||
return bit_count(a.mask) > bit_count(b.mask);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
unsigned instruction_decoder<tgc_c>::decode_instruction<traits<tgc_c>::code_word_t>(traits<tgc_c>::code_word_t instr){
|
|
||||||
auto res = std::find_if(std::begin(qlut[instr&0x3]), std::end(qlut[instr&0x3]), [instr](instruction_pattern const& e){
|
|
||||||
return !((instr&e.mask) ^ e.value );
|
|
||||||
});
|
|
||||||
return static_cast<unsigned>(res!=std::end(qlut[instr&0x3])? res->id : opcode_e::MAX_OPCODE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<instruction_decoder<tgc_c>> traits<tgc_c>::get_decoder(){
|
|
||||||
return std::make_unique<instruction_decoder<tgc_c>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,36 +15,43 @@ using tgc5a_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5a>;
|
|||||||
using tgc5b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5b>;
|
using tgc5b_plat_type = iss::arch::riscv_hart_m_p<iss::arch::tgc5b>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5C_XRB_NN
|
#ifdef CORE_TGC5C_XRB_NN
|
||||||
#include "riscv_hart_m_p.h"
|
|
||||||
#include "hwl.h"
|
#include "hwl.h"
|
||||||
|
#include "riscv_hart_m_p.h"
|
||||||
#include <iss/arch/tgc5c_xrb_nn.h>
|
#include <iss/arch/tgc5c_xrb_nn.h>
|
||||||
using tgc5c_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_m_p<iss::arch::tgc5c_xrb_nn>>;
|
using tgc5c_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_m_p<iss::arch::tgc5c_xrb_nn>>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5D
|
#ifdef CORE_TGC5D
|
||||||
#include "riscv_hart_mu_p.h"
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5d.h>
|
#include <iss/arch/tgc5d.h>
|
||||||
using tgc5d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
using tgc5d_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
|
||||||
|
iss::arch::FEAT_EXT_N)>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5D_XRB_MAC
|
#ifdef CORE_TGC5D_XRB_MAC
|
||||||
#include "riscv_hart_mu_p.h"
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5d_xrb_mac.h>
|
#include <iss/arch/tgc5d_xrb_mac.h>
|
||||||
using tgc5d_xrb_mac_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
using tgc5d_xrb_mac_plat_type =
|
||||||
|
iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_mac,
|
||||||
|
(iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5D_XRB_NN
|
#ifdef CORE_TGC5D_XRB_NN
|
||||||
#include "riscv_hart_mu_p.h"
|
|
||||||
#include "hwl.h"
|
#include "hwl.h"
|
||||||
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5d_xrb_nn.h>
|
#include <iss/arch/tgc5d_xrb_nn.h>
|
||||||
using tgc5d_xrb_nn_plat_type = iss::arch::hwl<iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_nn, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>>;
|
using tgc5d_xrb_nn_plat_type =
|
||||||
|
iss::arch::hwl<iss::arch::riscv_hart_mu_p<iss::arch::tgc5d_xrb_nn,
|
||||||
|
(iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5E
|
#ifdef CORE_TGC5E
|
||||||
#include "riscv_hart_mu_p.h"
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5e.h>
|
#include <iss/arch/tgc5e.h>
|
||||||
using tgc5e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N)>;
|
using tgc5e_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5e, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
|
||||||
|
iss::arch::FEAT_EXT_N)>;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CORE_TGC5X
|
#ifdef CORE_TGC5X
|
||||||
#include "riscv_hart_mu_p.h"
|
#include "riscv_hart_mu_p.h"
|
||||||
#include <iss/arch/tgc5x.h>
|
#include <iss/arch/tgc5x.h>
|
||||||
using tgc5x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC | iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>;
|
using tgc5x_plat_type = iss::arch::riscv_hart_mu_p<iss::arch::tgc5x, (iss::arch::features_e)(iss::arch::FEAT_PMP | iss::arch::FEAT_CLIC |
|
||||||
|
iss::arch::FEAT_EXT_N | iss::arch::FEAT_TCM)>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+18
-19
@@ -36,10 +36,10 @@
|
|||||||
#define _RISCV_HART_M_P_WT_CACHE_H
|
#define _RISCV_HART_M_P_WT_CACHE_H
|
||||||
|
|
||||||
#include <iss/vm_types.h>
|
#include <iss/vm_types.h>
|
||||||
#include <util/ities.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <util/ities.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace arch {
|
namespace arch {
|
||||||
@@ -50,11 +50,13 @@ struct line {
|
|||||||
uint64_t tag_addr{0};
|
uint64_t tag_addr{0};
|
||||||
state st{state::INVALID};
|
state st{state::INVALID};
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
line(unsigned line_sz): data(line_sz) {}
|
line(unsigned line_sz)
|
||||||
|
: data(line_sz) {}
|
||||||
};
|
};
|
||||||
struct set {
|
struct set {
|
||||||
std::vector<line> ways;
|
std::vector<line> ways;
|
||||||
set(unsigned ways_count, line const& l): ways(ways_count, l) {}
|
set(unsigned ways_count, line const& l)
|
||||||
|
: ways(ways_count, l) {}
|
||||||
};
|
};
|
||||||
struct cache {
|
struct cache {
|
||||||
std::vector<set> sets;
|
std::vector<set> sets;
|
||||||
@@ -69,7 +71,7 @@ struct cache {
|
|||||||
struct wt_policy {
|
struct wt_policy {
|
||||||
bool is_cacheline_hit(cache& c);
|
bool is_cacheline_hit(cache& c);
|
||||||
};
|
};
|
||||||
}
|
} // namespace cache
|
||||||
|
|
||||||
// write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy
|
// write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy
|
||||||
template <typename BASE> class wt_cache : public BASE {
|
template <typename BASE> class wt_cache : public BASE {
|
||||||
@@ -81,14 +83,15 @@ public:
|
|||||||
using mem_write_f = typename BASE::mem_write_f;
|
using mem_write_f = typename BASE::mem_write_f;
|
||||||
using phys_addr_t = typename BASE::phys_addr_t;
|
using phys_addr_t = typename BASE::phys_addr_t;
|
||||||
|
|
||||||
wt_cache();
|
wt_cache(feature_config cfg = feature_config{});
|
||||||
virtual ~wt_cache() = default;
|
virtual ~wt_cache() = default;
|
||||||
|
|
||||||
unsigned size{4096};
|
unsigned size{4096};
|
||||||
unsigned line_sz{32};
|
unsigned line_sz{64};
|
||||||
unsigned ways{1};
|
unsigned ways{1};
|
||||||
uint64_t io_address{0xf0000000};
|
uint64_t io_address{0xf0000000};
|
||||||
uint64_t io_addr_mask{0xf0000000};
|
uint64_t io_addr_mask{0xf0000000};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
iss::status read_cache(phys_addr_t addr, unsigned, uint8_t* const);
|
iss::status read_cache(phys_addr_t addr, unsigned, uint8_t* const);
|
||||||
iss::status write_cache(phys_addr_t addr, unsigned, uint8_t const* const);
|
iss::status write_cache(phys_addr_t addr, unsigned, uint8_t const* const);
|
||||||
@@ -96,14 +99,14 @@ protected:
|
|||||||
std::function<mem_write_f> cache_mem_wr_delegate;
|
std::function<mem_write_f> cache_mem_wr_delegate;
|
||||||
std::unique_ptr<cache::cache> dcache_ptr;
|
std::unique_ptr<cache::cache> dcache_ptr;
|
||||||
std::unique_ptr<cache::cache> icache_ptr;
|
std::unique_ptr<cache::cache> icache_ptr;
|
||||||
size_t get_way_select() {
|
size_t get_way_select() { return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename BASE>
|
template <typename BASE>
|
||||||
inline wt_cache<BASE>::wt_cache() {
|
inline wt_cache<BASE>::wt_cache(feature_config cfg)
|
||||||
|
: BASE(cfg)
|
||||||
|
, io_address{cfg.io_address}
|
||||||
|
, io_addr_mask{cfg.io_addr_mask} {
|
||||||
auto cb = base_class::replace_mem_access(
|
auto cb = base_class::replace_mem_access(
|
||||||
[this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return read_cache(a, l, d); },
|
[this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return read_cache(a, l, d); },
|
||||||
[this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return write_cache(a, l, d); });
|
[this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return write_cache(a, l, d); });
|
||||||
@@ -111,13 +114,12 @@ inline wt_cache<BASE>::wt_cache() {
|
|||||||
cache_mem_wr_delegate = cb.second;
|
cache_mem_wr_delegate = cb.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BASE>
|
template <typename BASE> iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
|
||||||
iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
|
|
||||||
if(!icache_ptr) {
|
if(!icache_ptr) {
|
||||||
icache_ptr.reset(new cache::cache(size, line_sz, ways));
|
icache_ptr.reset(new cache::cache(size, line_sz, ways));
|
||||||
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
|
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
|
||||||
}
|
}
|
||||||
if((a.val&io_addr_mask) != io_address) {
|
if((a.access & iss::access_type::FETCH) == iss::access_type::FETCH || (a.val & io_addr_mask) != io_address) {
|
||||||
auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
|
auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
|
||||||
auto tag_addr = a.val >> util::ilog2(line_sz);
|
auto tag_addr = a.val >> util::ilog2(line_sz);
|
||||||
auto& set = (is_fetch(a.access) ? icache_ptr : dcache_ptr)->sets[set_addr];
|
auto& set = (is_fetch(a.access) ? icache_ptr : dcache_ptr)->sets[set_addr];
|
||||||
@@ -143,8 +145,7 @@ iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uin
|
|||||||
return cache_mem_rd_delegate(a, l, d);
|
return cache_mem_rd_delegate(a, l, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename BASE>
|
template <typename BASE> iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
|
||||||
iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
|
|
||||||
if(!dcache_ptr)
|
if(!dcache_ptr)
|
||||||
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
|
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
|
||||||
auto res = cache_mem_wr_delegate(a, l, d);
|
auto res = cache_mem_wr_delegate(a, l, d);
|
||||||
@@ -164,8 +165,6 @@ iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, co
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace arch
|
} // namespace arch
|
||||||
} // namespace iss
|
} // namespace iss
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -30,8 +30,8 @@
|
|||||||
*
|
*
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#ifndef _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_
|
#ifndef _ISS_ARCH_DEBUGGER_RISCV_TARGET_ADAPTER_H_
|
||||||
#define _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_
|
#define _ISS_ARCH_DEBUGGER_RISCV_TARGET_ADAPTER_H_
|
||||||
|
|
||||||
#include "iss/arch_if.h"
|
#include "iss/arch_if.h"
|
||||||
#include <iss/arch/traits.h>
|
#include <iss/arch/traits.h>
|
||||||
@@ -48,6 +48,10 @@
|
|||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace debugger {
|
namespace debugger {
|
||||||
|
|
||||||
|
char const* const get_csr_name(unsigned);
|
||||||
|
constexpr auto csr_offset = 100U;
|
||||||
|
|
||||||
using namespace iss::arch;
|
using namespace iss::arch;
|
||||||
using namespace iss::debugger;
|
using namespace iss::debugger;
|
||||||
|
|
||||||
@@ -84,8 +88,7 @@ public:
|
|||||||
target byte order. If register is not available
|
target byte order. If register is not available
|
||||||
corresponding bytes in avail_buf are 0, otherwise
|
corresponding bytes in avail_buf are 0, otherwise
|
||||||
avail buf is 1 */
|
avail buf is 1 */
|
||||||
status read_single_register(unsigned int reg_no, std::vector<uint8_t> &buf,
|
status read_single_register(unsigned int reg_no, std::vector<uint8_t>& buf, std::vector<uint8_t>& avail_buf) override;
|
||||||
std::vector<uint8_t> &avail_buf) override;
|
|
||||||
|
|
||||||
/* Write one register. buf is 4-byte aligned and it is in target byte
|
/* Write one register. buf is 4-byte aligned and it is in target byte
|
||||||
order */
|
order */
|
||||||
@@ -103,8 +106,8 @@ public:
|
|||||||
|
|
||||||
status process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) override;
|
status process_query(unsigned int& mask, const rp_thread_ref& arg, rp_thread_info& info) override;
|
||||||
|
|
||||||
status thread_list_query(int first, const rp_thread_ref &arg, std::vector<rp_thread_ref> &result, size_t max_num,
|
status thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result, size_t max_num, size_t& num,
|
||||||
size_t &num, bool &done) override;
|
bool& done) override;
|
||||||
|
|
||||||
status current_thread_query(rp_thread_ref& thread) override;
|
status current_thread_query(rp_thread_ref& thread) override;
|
||||||
|
|
||||||
@@ -124,18 +127,23 @@ public:
|
|||||||
|
|
||||||
status remove_break(break_type type, uint64_t addr, unsigned int length) override;
|
status remove_break(break_type type, uint64_t addr, unsigned int length) override;
|
||||||
|
|
||||||
status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread,
|
status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, std::function<void(unsigned)> stop_callback) override;
|
||||||
std::function<void(unsigned)> stop_callback) override;
|
|
||||||
|
|
||||||
status target_xml_query(std::string& out_buf) override;
|
status target_xml_query(std::string& out_buf) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static inline constexpr addr_t map_addr(const addr_t& i) { return i; }
|
static inline constexpr addr_t map_addr(const addr_t& i) { return i; }
|
||||||
|
std::string csr_xml;
|
||||||
iss::arch_if* core;
|
iss::arch_if* core;
|
||||||
rp_thread_ref thread_idx;
|
rp_thread_ref thread_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename ARCH> typename std::enable_if<iss::arch::traits<ARCH>::FLEN != 0, unsigned>::type get_f0_offset() {
|
||||||
|
return iss::arch::traits<ARCH>::F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ARCH> typename std::enable_if<iss::arch::traits<ARCH>::FLEN == 0, unsigned>::type get_f0_offset() { return 0; }
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref& thread) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::set_gen_thread(rp_thread_ref& thread) {
|
||||||
thread_idx = thread;
|
thread_idx = thread;
|
||||||
return Ok;
|
return Ok;
|
||||||
@@ -158,9 +166,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::is_thread_alive(rp_t
|
|||||||
* set if all threads are processed.
|
* set if all threads are processed.
|
||||||
*/
|
*/
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref &arg,
|
status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result,
|
||||||
std::vector<rp_thread_ref> &result, size_t max_num, size_t &num,
|
size_t max_num, size_t& num, bool& done) {
|
||||||
bool &done) {
|
|
||||||
if(first == 0) {
|
if(first == 0) {
|
||||||
result.clear();
|
result.clear();
|
||||||
result.push_back(thread_idx);
|
result.push_back(thread_idx);
|
||||||
@@ -176,15 +183,31 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::current_thread_query
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
|
||||||
status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vector<uint8_t> &avail) {
|
CPPLOG(TRACE) << "reading target registers";
|
||||||
LOG(TRACE) << "reading target registers";
|
|
||||||
// return idx<0?:;
|
|
||||||
data.clear();
|
data.clear();
|
||||||
avail.clear();
|
avail.clear();
|
||||||
const uint8_t* reg_base = core->get_regs_base_ptr();
|
const uint8_t* reg_base = core->get_regs_base_ptr();
|
||||||
auto start_reg = arch::traits<ARCH>::X0;
|
auto start_reg = arch::traits<ARCH>::X0;
|
||||||
for (size_t reg_no = start_reg; reg_no < start_reg+33/*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) {
|
for(size_t i = 0; i < 33; ++i) {
|
||||||
|
if(i < arch::traits<ARCH>::RFS || i == arch::traits<ARCH>::PC) {
|
||||||
|
auto reg_no = i < 32 ? start_reg + i : arch::traits<ARCH>::PC;
|
||||||
|
unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
||||||
|
for(size_t j = 0; j < arch::traits<ARCH>::XLEN / 8; ++j) {
|
||||||
|
data.push_back(*(reg_base + offset + j));
|
||||||
|
avail.push_back(0xff);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(size_t j = 0; j < arch::traits<ARCH>::XLEN / 8; ++j) {
|
||||||
|
data.push_back(0);
|
||||||
|
avail.push_back(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(iss::arch::traits<ARCH>::FLEN > 0) {
|
||||||
|
auto fstart_reg = get_f0_offset<ARCH>();
|
||||||
|
for(size_t i = 0; i < 32; ++i) {
|
||||||
|
auto reg_no = fstart_reg + i;
|
||||||
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
|
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
|
||||||
unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
||||||
for(size_t j = 0; j < reg_width; ++j) {
|
for(size_t j = 0; j < reg_width; ++j) {
|
||||||
@@ -192,21 +215,7 @@ status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, st
|
|||||||
avail.push_back(0xff);
|
avail.push_back(0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// work around fill with F type registers
|
}
|
||||||
// if (arch::traits<ARCH>::NUM_REGS < 65) {
|
|
||||||
// auto reg_width = sizeof(typename arch::traits<ARCH>::reg_t);
|
|
||||||
// for (size_t reg_no = 0; reg_no < 33; ++reg_no) {
|
|
||||||
// for (size_t j = 0; j < reg_width; ++j) {
|
|
||||||
// data.push_back(0x0);
|
|
||||||
// avail.push_back(0x00);
|
|
||||||
// }
|
|
||||||
// // if(arch::traits<ARCH>::XLEN < 64)
|
|
||||||
// // for(unsigned j=0; j<4; ++j){
|
|
||||||
// // data.push_back(0x0);
|
|
||||||
// // avail.push_back(0x00);
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,34 +223,33 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons
|
|||||||
auto start_reg = arch::traits<ARCH>::X0;
|
auto start_reg = arch::traits<ARCH>::X0;
|
||||||
auto* reg_base = core->get_regs_base_ptr();
|
auto* reg_base = core->get_regs_base_ptr();
|
||||||
auto iter = data.data();
|
auto iter = data.data();
|
||||||
bool e_ext = arch::traits<ARCH>::PC<32;
|
auto iter_end = data.data() + data.size();
|
||||||
for (size_t reg_no = 0; reg_no < start_reg+33/*arch::traits<ARCH>::NUM_REGS*/; ++reg_no) {
|
for(size_t i = 0; i < 33 && iter < iter_end; ++i) {
|
||||||
if(e_ext && reg_no>15){
|
auto reg_width = arch::traits<ARCH>::XLEN / 8;
|
||||||
if(reg_no==32){
|
if(i < arch::traits<ARCH>::RFS) {
|
||||||
auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8;
|
auto offset = traits<ARCH>::reg_byte_offsets[start_reg + i];
|
||||||
|
std::copy(iter, iter + reg_width, reg_base + offset);
|
||||||
|
} else if(i == 32) {
|
||||||
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
|
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
|
||||||
std::copy(iter, iter + reg_width, reg_base);
|
std::copy(iter, iter + reg_width, reg_base + offset);
|
||||||
} else {
|
|
||||||
const uint64_t zero_val=0;
|
|
||||||
auto reg_width = arch::traits<ARCH>::reg_bit_widths[15] / 8;
|
|
||||||
auto iter = (uint8_t*)&zero_val;
|
|
||||||
std::copy(iter, iter + reg_width, reg_base);
|
|
||||||
}
|
}
|
||||||
} else {
|
iter += reg_width;
|
||||||
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
|
}
|
||||||
auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
if(iss::arch::traits<ARCH>::FLEN > 0) {
|
||||||
std::copy(iter, iter + reg_width, reg_base);
|
auto fstart_reg = get_f0_offset<ARCH>();
|
||||||
iter += 4;
|
auto reg_width = arch::traits<ARCH>::FLEN / 8;
|
||||||
reg_base += offset;
|
for(size_t i = 0; i < 32 && iter < iter_end; ++i) {
|
||||||
|
unsigned offset = traits<ARCH>::reg_byte_offsets[fstart_reg + i];
|
||||||
|
std::copy(iter, iter + reg_width, reg_base + offset);
|
||||||
|
iter += reg_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH>
|
||||||
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t> &data,
|
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
|
||||||
std::vector<uint8_t> &avail) {
|
if(reg_no < csr_offset) {
|
||||||
if (reg_no < 65) {
|
|
||||||
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
|
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
|
||||||
// arch::traits<ARCH>::reg_e>(reg_no))/8;
|
// arch::traits<ARCH>::reg_e>(reg_no))/8;
|
||||||
auto* reg_base = core->get_regs_base_ptr();
|
auto* reg_base = core->get_regs_base_ptr();
|
||||||
@@ -252,24 +260,24 @@ status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std
|
|||||||
std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin());
|
std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin());
|
||||||
std::fill(avail.begin(), avail.end(), 0xff);
|
std::fill(avail.begin(), avail.end(), 0xff);
|
||||||
} else {
|
} else {
|
||||||
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65);
|
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, reg_no - csr_offset);
|
||||||
data.resize(sizeof(typename traits<ARCH>::reg_t));
|
data.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||||
avail.resize(sizeof(typename traits<ARCH>::reg_t));
|
avail.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||||
std::fill(avail.begin(), avail.end(), 0xff);
|
std::fill(avail.begin(), avail.end(), 0xff);
|
||||||
core->read(a, data.size(), data.data());
|
core->read(a, data.size(), data.data());
|
||||||
|
std::fill(avail.begin(), avail.end(), 0xff);
|
||||||
}
|
}
|
||||||
return data.size() > 0 ? Ok : Err;
|
return data.size() > 0 ? Ok : Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH> status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t>& data) {
|
||||||
status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) {
|
if(reg_no < csr_offset) {
|
||||||
if (reg_no < 65) {
|
|
||||||
auto* reg_base = core->get_regs_base_ptr();
|
auto* reg_base = core->get_regs_base_ptr();
|
||||||
auto reg_width = arch::traits<ARCH>::reg_bit_widths[static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)] / 8;
|
auto reg_width = arch::traits<ARCH>::reg_bit_widths[static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)] / 8;
|
||||||
auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
|
||||||
std::copy(data.begin(), data.begin() + reg_width, reg_base + offset);
|
std::copy(data.begin(), data.begin() + reg_width, reg_base + offset);
|
||||||
} else {
|
} else {
|
||||||
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65);
|
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - csr_offset);
|
||||||
core->write(a, data.size(), data.data());
|
core->write(a, data.size(), data.data());
|
||||||
}
|
}
|
||||||
return Ok;
|
return Ok;
|
||||||
@@ -282,7 +290,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::read_mem(uint64_t ad
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t>& data) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t>& data) {
|
||||||
auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr});
|
auto a = map_addr({iss::access_type::DEBUG_WRITE, iss::address_type::VIRTUAL, 0, addr});
|
||||||
auto f = [&]() -> status { return core->write(a, data.size(), data.data()); };
|
auto f = [&]() -> status { return core->write(a, data.size(), data.data()); };
|
||||||
return srv->execute_syncronized(f);
|
return srv->execute_syncronized(f);
|
||||||
}
|
}
|
||||||
@@ -292,21 +300,16 @@ status riscv_target_adapter<ARCH>::process_query(unsigned int &mask, const rp_th
|
|||||||
return NotSupported;
|
return NotSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH> status riscv_target_adapter<ARCH>::offsets_query(uint64_t& text, uint64_t& data, uint64_t& bss) {
|
||||||
status riscv_target_adapter<ARCH>::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) {
|
|
||||||
text = 0;
|
text = 0;
|
||||||
data = 0;
|
data = 0;
|
||||||
bss = 0;
|
bss = 0;
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t &val) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t& val) { return NotSupported; }
|
||||||
return NotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string &out_buf) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string& out_buf) { return NotSupported; }
|
||||||
return NotSupported;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string& out_buf) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string& out_buf) {
|
||||||
if(first) {
|
if(first) {
|
||||||
@@ -317,8 +320,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH>
|
template <typename ARCH> status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref& thread, std::string& out_buf) {
|
||||||
status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) {
|
|
||||||
std::array<char, 20> buf;
|
std::array<char, 20> buf;
|
||||||
memset(buf.data(), 0, 20);
|
memset(buf.data(), 0, 20);
|
||||||
sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
|
sprintf(buf.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0);
|
||||||
@@ -340,9 +342,9 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(break_type
|
|||||||
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
||||||
auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length});
|
auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length});
|
||||||
target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val);
|
target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val);
|
||||||
LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex
|
CPPLOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val
|
||||||
<< saddr.val << std::dec;
|
<< std::dec;
|
||||||
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,14 +359,13 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t
|
|||||||
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
||||||
unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
|
unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
|
||||||
if(handle) {
|
if(handle) {
|
||||||
LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val
|
CPPLOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val << std::dec;
|
||||||
<< std::dec;
|
|
||||||
// TODO: check length of addr range
|
// TODO: check length of addr range
|
||||||
target_adapter_base::bp_lut.removeEntry(handle);
|
target_adapter_base::bp_lut.removeEntry(handle);
|
||||||
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
CPPLOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
|
||||||
return Err;
|
return Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,93 +383,57 @@ status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string& out_buf) {
|
template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std::string& out_buf) {
|
||||||
const std::string res{"<?xml version=\"1.0\"?><!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
|
if(!csr_xml.size()) {
|
||||||
"<target><architecture>riscv:rv32</architecture>"
|
std::ostringstream oss;
|
||||||
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
|
oss << "<?xml version=\"1.0\"?><!DOCTYPE feature SYSTEM \"gdb-target.dtd\"><target version=\"1.0\">\n";
|
||||||
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
|
if(iss::arch::traits<ARCH>::XLEN == 32)
|
||||||
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << "<architecture>riscv:rv32</architecture>\n";
|
||||||
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
|
else if(iss::arch::traits<ARCH>::XLEN == 64)
|
||||||
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <architectureriscv:rv64</architecture>\n";
|
||||||
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <feature name=\"org.gnu.gdb.riscv.cpu\">\n";
|
||||||
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
|
auto reg_base_num = iss::arch::traits<ARCH>::X0;
|
||||||
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
|
for(auto i = 0U; i < iss::arch::traits<ARCH>::RFS; ++i) {
|
||||||
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"x" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i]
|
||||||
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
|
<< "\" type=\"int\" regnum=\"" << i << "\"/>\n";
|
||||||
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
|
}
|
||||||
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"pc\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[iss::arch::traits<ARCH>::PC]
|
||||||
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
|
<< "\" type=\"code_ptr\" regnum=\"" << 32U << "\"/>\n";
|
||||||
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " </feature>\n";
|
||||||
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
|
if(iss::arch::traits<ARCH>::FLEN > 0) {
|
||||||
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <feature name=\"org.gnu.gdb.riscv.fpu\">\n";
|
||||||
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
|
auto reg_base_num = get_f0_offset<ARCH>();
|
||||||
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
|
auto type = iss::arch::traits<ARCH>::FLEN == 32 ? "ieee_single" : "riscv_double";
|
||||||
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
|
for(auto i = 0U; i < 32; ++i) {
|
||||||
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"f" << i << "\" bitsize=\"" << iss::arch::traits<ARCH>::reg_bit_widths[reg_base_num + i]
|
||||||
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
|
<< "\" type=\"" << type << "\" regnum=\"" << i + 33 << "\"/>\n";
|
||||||
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
|
}
|
||||||
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"fcsr\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"103\" type int/>\n";
|
||||||
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"fflags\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"101\" type int/>\n";
|
||||||
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <reg name=\"frm\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN << "\" regnum=\"102\" type int/>\n";
|
||||||
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " </feature>\n";
|
||||||
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
|
}
|
||||||
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
|
oss << " <feature name=\"org.gnu.gdb.riscv.csr\">\n";
|
||||||
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
|
std::vector<uint8_t> data;
|
||||||
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
|
std::vector<uint8_t> avail;
|
||||||
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
|
data.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||||
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
|
avail.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||||
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
|
for(auto i = 0U; i < 4096; ++i) {
|
||||||
//" </feature>\n"
|
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, i);
|
||||||
"</target>"};
|
std::fill(avail.begin(), avail.end(), 0xff);
|
||||||
out_buf = res;
|
auto res = core->read(a, data.size(), data.data());
|
||||||
|
if(res == iss::Ok) {
|
||||||
|
oss << " <reg name=\"" << get_csr_name(i) << "\" bitsize=\"" << iss::arch::traits<ARCH>::XLEN
|
||||||
|
<< "\" type=\"int\" regnum=\"" << (i + csr_offset) << "\"/>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oss << " </feature>\n";
|
||||||
|
oss << "</target>\n";
|
||||||
|
csr_xml = oss.str();
|
||||||
|
}
|
||||||
|
out_buf = csr_xml;
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
} // namespace debugger
|
||||||
|
} // namespace iss
|
||||||
|
|
||||||
/*
|
#endif /* _ISS_ARCH_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */
|
||||||
*
|
|
||||||
<?xml version="1.0"?>
|
|
||||||
<!DOCTYPE target SYSTEM "gdb-target.dtd">
|
|
||||||
<target>
|
|
||||||
<architecture>riscv:rv32</architecture>
|
|
||||||
|
|
||||||
<feature name="org.gnu.gdb.riscv.rv32i">
|
|
||||||
<reg name="x0" bitsize="32" group="general"/>
|
|
||||||
<reg name="x1" bitsize="32" group="general"/>
|
|
||||||
<reg name="x2" bitsize="32" group="general"/>
|
|
||||||
<reg name="x3" bitsize="32" group="general"/>
|
|
||||||
<reg name="x4" bitsize="32" group="general"/>
|
|
||||||
<reg name="x5" bitsize="32" group="general"/>
|
|
||||||
<reg name="x6" bitsize="32" group="general"/>
|
|
||||||
<reg name="x7" bitsize="32" group="general"/>
|
|
||||||
<reg name="x8" bitsize="32" group="general"/>
|
|
||||||
<reg name="x9" bitsize="32" group="general"/>
|
|
||||||
<reg name="x10" bitsize="32" group="general"/>
|
|
||||||
<reg name="x11" bitsize="32" group="general"/>
|
|
||||||
<reg name="x12" bitsize="32" group="general"/>
|
|
||||||
<reg name="x13" bitsize="32" group="general"/>
|
|
||||||
<reg name="x14" bitsize="32" group="general"/>
|
|
||||||
<reg name="x15" bitsize="32" group="general"/>
|
|
||||||
<reg name="x16" bitsize="32" group="general"/>
|
|
||||||
<reg name="x17" bitsize="32" group="general"/>
|
|
||||||
<reg name="x18" bitsize="32" group="general"/>
|
|
||||||
<reg name="x19" bitsize="32" group="general"/>
|
|
||||||
<reg name="x20" bitsize="32" group="general"/>
|
|
||||||
<reg name="x21" bitsize="32" group="general"/>
|
|
||||||
<reg name="x22" bitsize="32" group="general"/>
|
|
||||||
<reg name="x23" bitsize="32" group="general"/>
|
|
||||||
<reg name="x24" bitsize="32" group="general"/>
|
|
||||||
<reg name="x25" bitsize="32" group="general"/>
|
|
||||||
<reg name="x26" bitsize="32" group="general"/>
|
|
||||||
<reg name="x27" bitsize="32" group="general"/>
|
|
||||||
<reg name="x28" bitsize="32" group="general"/>
|
|
||||||
<reg name="x29" bitsize="32" group="general"/>
|
|
||||||
<reg name="x30" bitsize="32" group="general"/>
|
|
||||||
<reg name="x31" bitsize="32" group="general"/>
|
|
||||||
</feature>
|
|
||||||
|
|
||||||
</target>
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */
|
|
||||||
+11
-11
@@ -33,12 +33,12 @@
|
|||||||
#ifndef _ISS_FACTORY_H_
|
#ifndef _ISS_FACTORY_H_
|
||||||
#define _ISS_FACTORY_H_
|
#define _ISS_FACTORY_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
#include <iss/iss.h>
|
#include <iss/iss.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <algorithm>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
@@ -46,8 +46,7 @@ namespace iss {
|
|||||||
using cpu_ptr = std::unique_ptr<iss::arch_if>;
|
using cpu_ptr = std::unique_ptr<iss::arch_if>;
|
||||||
using vm_ptr = std::unique_ptr<iss::vm_if>;
|
using vm_ptr = std::unique_ptr<iss::vm_if>;
|
||||||
|
|
||||||
template<typename PLAT>
|
template <typename PLAT> std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port) {
|
||||||
std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port){
|
|
||||||
using core_type = typename PLAT::core;
|
using core_type = typename PLAT::core;
|
||||||
core_type* lcpu = new PLAT();
|
core_type* lcpu = new PLAT();
|
||||||
if(backend == "interp")
|
if(backend == "interp")
|
||||||
@@ -63,7 +62,6 @@ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_
|
|||||||
return {nullptr, nullptr};
|
return {nullptr, nullptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class core_factory {
|
class core_factory {
|
||||||
using cpu_ptr = std::unique_ptr<iss::arch_if>;
|
using cpu_ptr = std::unique_ptr<iss::arch_if>;
|
||||||
using vm_ptr = std::unique_ptr<iss::vm_if>;
|
using vm_ptr = std::unique_ptr<iss::vm_if>;
|
||||||
@@ -78,7 +76,10 @@ class core_factory {
|
|||||||
core_factory& operator=(const core_factory&) = delete;
|
core_factory& operator=(const core_factory&) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static core_factory & instance() { static core_factory bf; return bf; }
|
static core_factory& instance() {
|
||||||
|
static core_factory bf;
|
||||||
|
return bf;
|
||||||
|
}
|
||||||
|
|
||||||
bool register_creator(const std::string& className, create_fn const& fn) {
|
bool register_creator(const std::string& className, create_fn const& fn) {
|
||||||
registry[className] = fn;
|
registry[className] = fn;
|
||||||
@@ -94,13 +95,12 @@ public:
|
|||||||
|
|
||||||
std::vector<std::string> get_names() {
|
std::vector<std::string> get_names() {
|
||||||
std::vector<std::string> keys{registry.size()};
|
std::vector<std::string> keys{registry.size()};
|
||||||
std::transform(std::begin(registry), std::end(registry), std::begin(keys), [](std::pair<std::string, create_fn> const& p){
|
std::transform(std::begin(registry), std::end(registry), std::begin(keys),
|
||||||
return p.first;
|
[](std::pair<std::string, create_fn> const& p) { return p.first; });
|
||||||
});
|
|
||||||
return keys;
|
return keys;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // namespace iss
|
||||||
|
|
||||||
#endif /* _ISS_FACTORY_H_ */
|
#endif /* _ISS_FACTORY_H_ */
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# pctrace
|
||||||
|
|
||||||
|
Trace functionality to allow visualizing coverage in lcov and cachegrind tools. Use environment variables NOCOMPRES and REGDUMP to toggle functionality.
|
||||||
|
- NOCOMPRES: any value turns off the LZ4 compression
|
||||||
|
- REGDUMP: any value switches to tracing the registers instead. Also turns off compression.
|
||||||
|
|
||||||
|
Known Bugs:
|
||||||
|
- currently does not work correctly with jit backends, the plugin cant tell if instructions are compressed. Additionaly the cost of instrs that raise a trap is not known. It takes the cost of the instrid -1 (0 at the moment).
|
||||||
@@ -33,86 +33,82 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "cycle_estimate.h"
|
#include "cycle_estimate.h"
|
||||||
|
#include <iss/plugin/calculator.h>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <rapidjson/document.h>
|
|
||||||
#include <rapidjson/istreamwrapper.h>
|
|
||||||
#include <rapidjson/writer.h>
|
|
||||||
#include <rapidjson/stringbuffer.h>
|
|
||||||
#include <rapidjson/ostreamwrapper.h>
|
|
||||||
#include <rapidjson/error/en.h>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace rapidjson;
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
|
iss::plugin::cycle_estimate::cycle_estimate(string const& config_file_name)
|
||||||
: instr_if(nullptr)
|
: instr_if(nullptr)
|
||||||
, config_file_name(config_file_name)
|
, config_file_name(config_file_name) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
iss::plugin::cycle_estimate::~cycle_estimate() {
|
iss::plugin::cycle_estimate::~cycle_estimate() = default;
|
||||||
}
|
|
||||||
|
|
||||||
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
|
bool iss::plugin::cycle_estimate::registration(const char* const version, vm_if& vm) {
|
||||||
instr_if = vm.get_arch()->get_instrumentation_if();
|
instr_if = vm.get_arch()->get_instrumentation_if();
|
||||||
if(!instr_if) return false;
|
assert(instr_if && "No instrumentation interface available but callback executed");
|
||||||
|
reg_base_ptr = reinterpret_cast<uint32_t*>(vm.get_arch()->get_regs_base_ptr());
|
||||||
|
if(!instr_if)
|
||||||
|
return false;
|
||||||
const string core_name = instr_if->core_type_name();
|
const string core_name = instr_if->core_type_name();
|
||||||
if(config_file_name.length() > 0) {
|
if(config_file_name.length() > 0) {
|
||||||
ifstream is(config_file_name);
|
std::ifstream is(config_file_name);
|
||||||
if(is.is_open()) {
|
if(is.is_open()) {
|
||||||
try {
|
try {
|
||||||
IStreamWrapper isw(is);
|
auto root = YAML::LoadAll(is);
|
||||||
Document d;
|
if(root.size() != 1) {
|
||||||
ParseResult ok = d.ParseStream(isw);
|
CPPLOG(ERR) << "Too many root nodes in YAML file " << config_file_name;
|
||||||
if(ok) {
|
|
||||||
Value& val = d[core_name.c_str()];
|
|
||||||
if(val.IsArray()){
|
|
||||||
delays.reserve(val.Size());
|
|
||||||
for (auto it = val.Begin(); it != val.End(); ++it) {
|
|
||||||
auto& name = (*it)["name"];
|
|
||||||
auto& size = (*it)["size"];
|
|
||||||
auto& delay = (*it)["delay"];
|
|
||||||
auto& branch = (*it)["branch"];
|
|
||||||
if(delay.IsArray()) {
|
|
||||||
auto dt = delay[0].Get<unsigned>();
|
|
||||||
auto dnt = delay[1].Get<unsigned>();
|
|
||||||
delays.push_back(instr_desc{size.Get<unsigned>(), dt, dnt, branch.Get<bool>()});
|
|
||||||
} else if(delay.Is<unsigned>()) {
|
|
||||||
auto d = delay.Get<unsigned>();
|
|
||||||
delays.push_back(instr_desc{size.Get<unsigned>(), d, d, branch.Get<bool>()});
|
|
||||||
} else
|
|
||||||
throw runtime_error("JSON parse error");
|
|
||||||
}
|
}
|
||||||
|
for(auto p : root[0]) {
|
||||||
|
auto isa_subset = p.first;
|
||||||
|
auto instructions = p.second;
|
||||||
|
for(auto const& instr : instructions) {
|
||||||
|
auto idx = instr.second["index"].as<unsigned>();
|
||||||
|
if(delays.size() <= idx)
|
||||||
|
delays.resize(idx + 1);
|
||||||
|
auto& res = delays[idx];
|
||||||
|
res.is_branch = instr.second["branch"].as<bool>();
|
||||||
|
auto delay = instr.second["delay"];
|
||||||
|
if(delay.IsSequence()) {
|
||||||
|
res.not_taken = delay[0].as<uint64_t>();
|
||||||
|
res.taken = delay[1].as<uint64_t>();
|
||||||
} else {
|
} else {
|
||||||
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl;
|
try {
|
||||||
|
res.not_taken = delay.as<uint64_t>();
|
||||||
|
res.taken = res.not_taken;
|
||||||
|
} catch(const YAML::BadConversion& e) {
|
||||||
|
res.f = iss::plugin::calculator(reg_base_ptr, delay.as<std::string>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(YAML::ParserException& e) {
|
||||||
|
CPPLOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(ERR)<<"plugin cycle_estimate: could not parse in JSON file at "<< ok.Offset()<<": "<<GetParseError_En(ok.Code())<<endl;
|
CPPLOG(ERR) << "Could not open input file " << config_file_name;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (runtime_error &e) {
|
|
||||||
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(ERR) << "Could not open input file " << config_file_name;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
|
void iss::plugin::cycle_estimate::callback(instr_info_t instr_info) {
|
||||||
assert(instr_if && "No instrumentation interface available but callback executed");
|
size_t instr_id = instr_info.instr_id;
|
||||||
auto entry = delays[instr_info.instr_id];
|
auto& entry = instr_id < delays.size() ? delays[instr_id] : illegal_desc;
|
||||||
bool taken = instr_if->is_branch_taken();
|
if(instr_info.phase_id == PRE_SYNC) {
|
||||||
if (taken && (entry.taken > 1))
|
if(entry.f)
|
||||||
instr_if->update_last_instr_cycles(entry.taken);
|
current_delay = entry.f(instr_if->get_instr_word());
|
||||||
else if (entry.not_taken > 1)
|
} else {
|
||||||
instr_if->update_last_instr_cycles(entry.not_taken);
|
if(!entry.f)
|
||||||
|
current_delay = instr_if->is_branch_taken() ? entry.taken : entry.not_taken;
|
||||||
|
if(current_delay > 1)
|
||||||
|
instr_if->update_last_instr_cycles(current_delay);
|
||||||
|
current_delay = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "iss/instrumentation_if.h"
|
#include "iss/instrumentation_if.h"
|
||||||
#include "iss/vm_plugin.h"
|
#include "iss/vm_plugin.h"
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -46,18 +47,13 @@ namespace iss {
|
|||||||
namespace plugin {
|
namespace plugin {
|
||||||
|
|
||||||
class cycle_estimate : public vm_plugin {
|
class cycle_estimate : public vm_plugin {
|
||||||
BEGIN_BF_DECL(instr_desc, uint32_t)
|
struct instr_desc {
|
||||||
BF_FIELD(taken, 24, 8)
|
size_t size{0};
|
||||||
BF_FIELD(not_taken, 16, 8)
|
bool is_branch{false};
|
||||||
BF_FIELD(is_branch, 8, 8)
|
unsigned not_taken{1};
|
||||||
BF_FIELD(size, 0, 8)
|
unsigned taken{1};
|
||||||
instr_desc(uint32_t size, uint32_t taken, uint32_t not_taken, bool branch): instr_desc() {
|
std::function<unsigned(uint64_t)> f;
|
||||||
this->size=size;
|
};
|
||||||
this->taken=taken;
|
|
||||||
this->not_taken=not_taken;
|
|
||||||
this->is_branch=branch;
|
|
||||||
}
|
|
||||||
END_BF_DECL();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cycle_estimate() = delete;
|
cycle_estimate() = delete;
|
||||||
@@ -76,13 +72,16 @@ public:
|
|||||||
|
|
||||||
bool registration(const char* const version, vm_if& arch) override;
|
bool registration(const char* const version, vm_if& arch) override;
|
||||||
|
|
||||||
sync_type get_sync() override { return POST_SYNC; };
|
sync_type get_sync() override { return ALL_SYNC; };
|
||||||
|
|
||||||
void callback(instr_info_t instr_info) override;
|
void callback(instr_info_t instr_info) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
iss::instrumentation_if *instr_if;
|
iss::instrumentation_if* instr_if{nullptr};
|
||||||
|
uint32_t* reg_base_ptr{nullptr};
|
||||||
|
instr_desc illegal_desc{};
|
||||||
std::vector<instr_desc> delays;
|
std::vector<instr_desc> delays;
|
||||||
|
unsigned current_delay{0};
|
||||||
struct pair_hash {
|
struct pair_hash {
|
||||||
size_t operator()(const std::pair<uint64_t, uint64_t>& p) const {
|
size_t operator()(const std::pair<uint64_t, uint64_t>& p) const {
|
||||||
std::hash<uint64_t> hash;
|
std::hash<uint64_t> hash;
|
||||||
@@ -92,7 +91,7 @@ private:
|
|||||||
std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks;
|
std::unordered_map<std::pair<uint64_t, uint64_t>, uint64_t, pair_hash> blocks;
|
||||||
std::string config_file_name;
|
std::string config_file_name;
|
||||||
};
|
};
|
||||||
}
|
} // namespace plugin
|
||||||
}
|
} // namespace iss
|
||||||
|
|
||||||
#endif /* _ISS_PLUGIN_CYCLE_ESTIMATE_H_ */
|
#endif /* _ISS_PLUGIN_CYCLE_ESTIMATE_H_ */
|
||||||
@@ -34,22 +34,45 @@
|
|||||||
|
|
||||||
#include "instruction_count.h"
|
#include "instruction_count.h"
|
||||||
#include <iss/instrumentation_if.h>
|
#include <iss/instrumentation_if.h>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include <iss/arch_if.h>
|
#include <iss/arch_if.h>
|
||||||
#include <util/logging.h>
|
#include <util/logging.h>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
iss::plugin::instruction_count::instruction_count(std::string config_file_name) {
|
iss::plugin::instruction_count::instruction_count(std::string config_file_name) {
|
||||||
if(config_file_name.length() > 0) {
|
if(config_file_name.length() > 0) {
|
||||||
std::ifstream is(config_file_name);
|
std::ifstream is(config_file_name);
|
||||||
if(is.is_open()) {
|
if(is.is_open()) {
|
||||||
try {
|
try {
|
||||||
is >> root;
|
auto root = YAML::LoadAll(is);
|
||||||
} catch (Json::RuntimeError &e) {
|
if(root.size() != 1) {
|
||||||
LOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
CPPLOG(ERR) << "Too many rro nodes in YAML file " << config_file_name;
|
||||||
|
}
|
||||||
|
for(auto p : root[0]) {
|
||||||
|
auto isa_subset = p.first;
|
||||||
|
auto instructions = p.second;
|
||||||
|
for(auto const& instr : instructions) {
|
||||||
|
instr_delay res;
|
||||||
|
res.instr_name = instr.first.as<std::string>();
|
||||||
|
res.size = instr.second["encoding"].as<std::string>().size() - 2; // not counting 0b
|
||||||
|
auto delay = instr.second["delay"];
|
||||||
|
if(delay.IsSequence()) {
|
||||||
|
res.not_taken_delay = delay[0].as<uint64_t>();
|
||||||
|
res.taken_delay = delay[1].as<uint64_t>();
|
||||||
|
} else {
|
||||||
|
res.not_taken_delay = delay.as<uint64_t>();
|
||||||
|
res.taken_delay = res.not_taken_delay;
|
||||||
|
}
|
||||||
|
delays.push_back(std::move(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rep_counts.resize(delays.size());
|
||||||
|
} catch(YAML::ParserException& e) {
|
||||||
|
CPPLOG(ERR) << "Could not parse input file " << config_file_name << ", reason: " << e.what();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(ERR) << "Could not open input file " << config_file_name;
|
CPPLOG(ERR) << "Could not open input file " << config_file_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,39 +80,17 @@ iss::plugin::instruction_count::instruction_count(std::string config_file_name)
|
|||||||
iss::plugin::instruction_count::~instruction_count() {
|
iss::plugin::instruction_count::~instruction_count() {
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
for(auto it : delays) {
|
for(auto it : delays) {
|
||||||
if(rep_counts[idx]>0)
|
if(rep_counts[idx] > 0 && it.instr_name.find("__" != 0))
|
||||||
LOG(INFO)<<it.instr_name<<";"<<rep_counts[idx];
|
CPPLOG(INFO) << it.instr_name << ";" << rep_counts[idx];
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool iss::plugin::instruction_count::registration(const char* const version, vm_if& vm) {
|
bool iss::plugin::instruction_count::registration(const char* const version, vm_if& vm) {
|
||||||
auto instr_if = vm.get_arch()->get_instrumentation_if();
|
auto instr_if = vm.get_arch()->get_instrumentation_if();
|
||||||
if(!instr_if) return false;
|
if(!instr_if)
|
||||||
const std::string core_name = instr_if->core_type_name();
|
return false;
|
||||||
Json::Value &val = root[core_name];
|
|
||||||
if(!val.isNull() && val.isArray()){
|
|
||||||
delays.reserve(val.size());
|
|
||||||
for(auto it:val){
|
|
||||||
auto name = it["name"];
|
|
||||||
auto size = it["size"];
|
|
||||||
auto delay = it["delay"];
|
|
||||||
if(!name.isString() || !size.isUInt() || !(delay.isUInt() || delay.isArray())) throw std::runtime_error("JSON parse error");
|
|
||||||
if(delay.isUInt()){
|
|
||||||
const instr_delay entry{name.asCString(), size.asUInt(), delay.asUInt(), 0};
|
|
||||||
delays.push_back(entry);
|
|
||||||
} else {
|
|
||||||
const instr_delay entry{name.asCString(), size.asUInt(), delay[0].asUInt(), delay[1].asUInt()};
|
|
||||||
delays.push_back(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rep_counts.resize(delays.size());
|
|
||||||
} else {
|
|
||||||
LOG(ERR)<<"plugin instruction_count: could not find an entry for "<<core_name<<" in JSON file"<<std::endl;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iss::plugin::instruction_count::callback(instr_info_t instr_info) {
|
void iss::plugin::instruction_count::callback(instr_info_t instr_info) { rep_counts[instr_info.instr_id]++; }
|
||||||
rep_counts[instr_info.instr_id]++;
|
|
||||||
}
|
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
#define _ISS_PLUGIN_INSTRUCTION_COUNTER_H_
|
#define _ISS_PLUGIN_INSTRUCTION_COUNTER_H_
|
||||||
|
|
||||||
#include <iss/vm_plugin.h>
|
#include <iss/vm_plugin.h>
|
||||||
#include <json/json.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace iss {
|
namespace iss {
|
||||||
namespace plugin {
|
namespace plugin {
|
||||||
@@ -72,11 +72,10 @@ public:
|
|||||||
void callback(instr_info_t) override;
|
void callback(instr_info_t) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Json::Value root;
|
|
||||||
std::vector<instr_delay> delays;
|
std::vector<instr_delay> delays;
|
||||||
std::vector<uint64_t> rep_counts;
|
std::vector<uint64_t> rep_counts;
|
||||||
};
|
};
|
||||||
}
|
} // namespace plugin
|
||||||
}
|
} // namespace iss
|
||||||
|
|
||||||
#endif /* _ISS_PLUGIN_INSTRUCTION_COUNTER_H_ */
|
#endif /* _ISS_PLUGIN_INSTRUCTION_COUNTER_H_ */
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright (C) 2017 - 2023, MINRES Technologies GmbH
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
||||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* alex.com - initial implementation
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
#include <iss/arch_if.h>
|
|
||||||
#include <iss/plugin/pctrace.h>
|
|
||||||
#include <util/logging.h>
|
|
||||||
#include <util/ities.h>
|
|
||||||
#include <rapidjson/document.h>
|
|
||||||
#include <rapidjson/istreamwrapper.h>
|
|
||||||
#include <rapidjson/writer.h>
|
|
||||||
#include <rapidjson/stringbuffer.h>
|
|
||||||
#include <rapidjson/ostreamwrapper.h>
|
|
||||||
#include <rapidjson/error/en.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#ifdef WITH_LZ4
|
|
||||||
#include <lz4frame.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace iss {
|
|
||||||
namespace plugin {
|
|
||||||
|
|
||||||
using namespace rapidjson;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#ifdef WITH_LZ4
|
|
||||||
class lz4compress_steambuf: public std::streambuf {
|
|
||||||
public:
|
|
||||||
lz4compress_steambuf(const lz4compress_steambuf&) = delete;
|
|
||||||
lz4compress_steambuf& operator=(const lz4compress_steambuf&) = delete;
|
|
||||||
lz4compress_steambuf(std::ostream &sink, size_t buf_size)
|
|
||||||
: sink(sink)
|
|
||||||
, src_buf(buf_size)
|
|
||||||
, dest_buf(LZ4F_compressBound(buf_size, nullptr))
|
|
||||||
{
|
|
||||||
auto errCode = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
|
||||||
if (LZ4F_isError(errCode) != 0)
|
|
||||||
throw std::runtime_error(std::string("Failed to create LZ4 context: ") + LZ4F_getErrorName(errCode));
|
|
||||||
size_t ret = LZ4F_compressBegin(ctx, &dest_buf.front(), dest_buf.capacity(), nullptr);
|
|
||||||
if (LZ4F_isError(ret) != 0)
|
|
||||||
throw std::runtime_error(std::string("Failed to start LZ4 compression: ") + LZ4F_getErrorName(ret));
|
|
||||||
setp(src_buf.data(), src_buf.data() + src_buf.size() - 1);
|
|
||||||
sink.write(dest_buf.data(), ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
~lz4compress_steambuf() {
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void close() {
|
|
||||||
if (closed)
|
|
||||||
return;
|
|
||||||
sync();
|
|
||||||
auto ret = LZ4F_compressEnd(ctx, dest_buf.data(), dest_buf.capacity(), nullptr);
|
|
||||||
if (LZ4F_isError(ret) != 0)
|
|
||||||
throw std::runtime_error(std::string("Failed to finish LZ4 compression: ") + LZ4F_getErrorName(ret));
|
|
||||||
sink.write(dest_buf.data(), ret);
|
|
||||||
LZ4F_freeCompressionContext(ctx);
|
|
||||||
closed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int_type overflow(int_type ch) override {
|
|
||||||
compress_and_write();
|
|
||||||
*pptr() = static_cast<char_type>(ch);
|
|
||||||
pbump(1);
|
|
||||||
return ch;
|
|
||||||
}
|
|
||||||
|
|
||||||
int_type sync() override {
|
|
||||||
compress_and_write();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void compress_and_write() {
|
|
||||||
if (closed)
|
|
||||||
throw std::runtime_error("Cannot write to closed stream");
|
|
||||||
if(auto orig_size = pptr() - pbase()){
|
|
||||||
auto ret = LZ4F_compressUpdate(ctx, dest_buf.data(), dest_buf.capacity(), pbase(), orig_size, nullptr);
|
|
||||||
if (LZ4F_isError(ret) != 0)
|
|
||||||
throw std::runtime_error(std::string("LZ4 compression failed: ") + LZ4F_getErrorName(ret));
|
|
||||||
if(ret) sink.write(dest_buf.data(), ret);
|
|
||||||
pbump(-orig_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream &sink;
|
|
||||||
std::vector<char> src_buf;
|
|
||||||
std::vector<char> dest_buf;
|
|
||||||
LZ4F_compressionContext_t ctx{ nullptr };
|
|
||||||
bool closed{ false };
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pctrace::pctrace(std::string const &filename)
|
|
||||||
: instr_if(nullptr)
|
|
||||||
, filename(filename)
|
|
||||||
, output("output.trc")
|
|
||||||
#ifdef WITH_LZ4
|
|
||||||
, strbuf(new lz4compress_steambuf(output, 4096))
|
|
||||||
, ostr(strbuf.get())
|
|
||||||
#endif
|
|
||||||
{ }
|
|
||||||
|
|
||||||
pctrace::~pctrace() { }
|
|
||||||
|
|
||||||
bool pctrace::registration(const char *const version, vm_if& vm) {
|
|
||||||
instr_if = vm.get_arch()->get_instrumentation_if();
|
|
||||||
if(!instr_if) return false;
|
|
||||||
const string core_name = instr_if->core_type_name();
|
|
||||||
if (filename.length() > 0) {
|
|
||||||
ifstream is(filename);
|
|
||||||
if (is.is_open()) {
|
|
||||||
try {
|
|
||||||
IStreamWrapper isw(is);
|
|
||||||
Document d;
|
|
||||||
ParseResult ok = d.ParseStream(isw);
|
|
||||||
if(ok) {
|
|
||||||
Value& val = d[core_name.c_str()];
|
|
||||||
if(val.IsArray()){
|
|
||||||
delays.reserve(val.Size());
|
|
||||||
for (auto it = val.Begin(); it != val.End(); ++it) {
|
|
||||||
auto& name = (*it)["name"];
|
|
||||||
auto& size = (*it)["size"];
|
|
||||||
auto& delay = (*it)["delay"];
|
|
||||||
auto& branch = (*it)["branch"];
|
|
||||||
if(delay.IsArray()) {
|
|
||||||
auto dt = delay[0].Get<unsigned>();
|
|
||||||
auto dnt = delay[1].Get<unsigned>();
|
|
||||||
delays.push_back(instr_desc{size.Get<unsigned>(), dt, dnt, branch.Get<bool>()});
|
|
||||||
} else if(delay.Is<unsigned>()) {
|
|
||||||
auto d = delay.Get<unsigned>();
|
|
||||||
delays.push_back(instr_desc{size.Get<unsigned>(), d, d, branch.Get<bool>()});
|
|
||||||
} else
|
|
||||||
throw runtime_error("JSON parse error");
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<<core_name<<" in JSON file"<<endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(ERR)<<"plugin cycle_estimate: could not parse in JSON file at "<< ok.Offset()<<": "<<GetParseError_En(ok.Code())<<endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (runtime_error &e) {
|
|
||||||
LOG(ERR) << "Could not parse input file " << filename << ", reason: " << e.what();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(ERR) << "Could not open input file " << filename;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pctrace::callback(instr_info_t iinfo) {
|
|
||||||
auto delay = 0;
|
|
||||||
size_t id = iinfo.instr_id;
|
|
||||||
auto entry = delays[id];
|
|
||||||
auto instr = instr_if->get_instr_word();
|
|
||||||
auto call = id==65 || id ==86 || ((id==2 || id==3) && bit_sub<7,5>(instr)!=0) ;//not taking care of tail calls (jalr with loading x6)
|
|
||||||
bool taken = instr_if->is_branch_taken();
|
|
||||||
bool compressed = (instr&0x3)!=0x3;
|
|
||||||
if (taken) {
|
|
||||||
delay = entry.taken;
|
|
||||||
if(entry.taken > 1)
|
|
||||||
instr_if->update_last_instr_cycles(entry.taken);
|
|
||||||
} else {
|
|
||||||
delay = entry.not_taken;
|
|
||||||
if (entry.not_taken > 1)
|
|
||||||
instr_if->update_last_instr_cycles(entry.not_taken);
|
|
||||||
}
|
|
||||||
#ifndef WITH_LZ4
|
|
||||||
output<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n";
|
|
||||||
#else
|
|
||||||
auto rdbuf=ostr.rdbuf();
|
|
||||||
ostr<<std::hex <<"0x" << instr_if->get_pc() <<"," << delay <<"," << call<<","<<(compressed?2:4) <<"\n";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loaded 100 of 116 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user