Compare commits
605 Commits
hotfix/lat
...
featture/i
| Author | SHA1 | Date | |
|---|---|---|---|
| 071cb4fdac | |||
| dd937710a7 | |||
| 047e2e12b0 | |||
| fe3ed49519 | |||
| 1afd77a942 | |||
| cdf5038e59 | |||
| 651897e1e4 | |||
| a1803c61c1 | |||
| bfa2182f8e | |||
| b01c9b27e5 | |||
| 07f394d5ff | |||
| 7e97329e78 | |||
| 8f5d666b7d | |||
| cc123939ce | |||
| a2e5405e25 | |||
| cd3ec0b79d | |||
| 0e35a2a8c9 | |||
| 8220c00a3d | |||
| ec5fb1e87e | |||
| 453407568c | |||
| 0fe9e6ebc8 | |||
| 484d9dbe08 | |||
| 7a7035f267 | |||
| d9f1e5d31b | |||
| 7b35f45a48 | |||
| ece6f7290f | |||
| 2166a6d81e | |||
| fe9f2a5455 | |||
| 42bf6ee380 | |||
| f0b582df6c | |||
| 6fcb3dbb66 | |||
| c01eb39a76 | |||
| 08280a094f | |||
| ae90adc854 | |||
| cd358198ad | |||
| 8746003d3e | |||
| 60d2b45a81 | |||
| 0264c5d66f | |||
| 528c2536af | |||
| 19e38ec898 | |||
| fd11ce18c4 | |||
| 9b7a9fa273 | |||
| e24c1874c4 | |||
| 221d2ee38c | |||
| 877cad27ba | |||
| a26505cb5c | |||
| c1277b6528 | |||
| 63889b02e7 | |||
| f049d8cbb3 | |||
| 28ac169cfe | |||
| a6f24db83a | |||
| e1911bc450 | |||
| 75d96bf18d | |||
| e59458aa0e | |||
| 77807fec01 | |||
| 6852d1d299 | |||
| ac1322d66b | |||
| 9ba9d2432c | |||
| c9b7962cd3 | |||
| ab31fd27c9 | |||
| b3f189145f | |||
| dd4416ab15 | |||
| 0027946f90 | |||
| feaff8c4a5 | |||
| af3e76cc98 | |||
| b1ceac2c2a | |||
| b5862039e7 | |||
| 51f3802394 | |||
| 6ce0d97e81 | |||
| 69c8fda5d2 | |||
| c1f9328528 | |||
| 2b85748279 | |||
| f7aa51b12e | |||
| 3428745a00 | |||
| 512b79a3e7 | |||
| 7a048f8b93 | |||
| 6f4daf91ed | |||
| 947d353bbf | |||
| b95f518c91 | |||
| 4cef0f57c1 | |||
| 28af695592 | |||
| f6cdd9d07c | |||
| 9e390971d4 | |||
| 2bb2e56310 | |||
| a0eeae7dd6 | |||
| 8f491ef36b | |||
| cbe4c2d62f | |||
| 31c6bb55f4 | |||
| 63d0162119 | |||
| 3b294d9da0 | |||
| 54233b448d | |||
| e238369e18 | |||
| cfc980a069 | |||
| 502f3e8df9 | |||
| 88475bfa55 | |||
| 71260a3ef4 | |||
| 23842742a6 | |||
| a13b7ac6d3 | |||
| aaebeaf023 | |||
| fb0f6255e9 | |||
| 57d5ea92be | |||
| 383d762abc | |||
| 03cbd305c6 | |||
| 9f5326c110 | |||
| f4718c6de3 | |||
| 53de21eef9 | |||
| d443c89c87 | |||
| 9a2df32d57 | |||
| be0f783af8 | |||
| 1089800682 | |||
| a6a6f51f0b | |||
| 21e1f791ad | |||
| be6f5791fa | |||
| d907dc7f54 | |||
| 75e81ce236 | |||
| 82a70efdb8 | |||
| 978c3db06e | |||
| 0e88664ff7 | |||
| 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 | |||
| 8ee3ac90f7 | |||
| d5763d2f36 | |||
| b5d915f389 | |||
| 813b40409d | |||
| c8a4a4c736 | |||
| 18e08cfc50 | |||
| 20e920338c | |||
| e151416f58 | |||
| 24de2bbdf5 | |||
| e68f9c573f | |||
| f38cc7d8b9 | |||
| 7af7e040da | |||
| 6e52af168b | |||
| bd0d15f3a2 | |||
| c78026b720 | |||
| edba497fa1 | |||
| 94e46b9968 | |||
| 9459632f6c | |||
| a0ca3cdfa5 | |||
| 720236ec3f | |||
| 957145ca84 | |||
| 0b719a4b57 | |||
| 57da07eb17 | |||
| b4b03f7850 | |||
| 145a0cf68b | |||
| 1cef7de8c7 | |||
| e95f422aab | |||
| 250ea3c980 | |||
| 7b31b8ca8e | |||
| 91a23a4a18 | |||
| 21d3250e1a | |||
| 2b094c3162 | |||
| a32c83e1be | |||
| 7e45a25218 | |||
| 87b4082633 | |||
| 4dbc7433a5 | |||
| 99a9970ddd | |||
| 0b5de90fb1 | |||
| 15cd36dcd4 | |||
| 2281ec4144 | |||
| 11c481cec2 | |||
| 60d07f2eb6 | |||
| a123beb301 | |||
| ee6218279e | |||
| ce5b2e60b9 | |||
| c792f50427 | |||
| 6ed7eafc5d | |||
| 8a5fe58d51 | |||
| 16cd6d5ff5 | |||
| ee2ded931d | |||
| 95ba5c901a | |||
| 32848ec396 | |||
| 6789cf4c32 | |||
| 3bc4884a9d | |||
| fd6b738168 | |||
| afdf8fb97f | |||
| cfa7b72363 | |||
| d330307ed5 | |||
| 916de2a26d | |||
| aa70d8a54a | |||
| b493745cd7 | |||
| f9e8e1d857 | |||
| 974d64a627 | |||
| d70489cbb8 | |||
| d990f1cf5d | |||
| 1672b01e62 | |||
| 00b0f101ac | |||
|
|
54f75f92ea | ||
|
|
0304aac9e5 | ||
| 8ff55d7b92 | |||
| f626ee2684 | |||
| a8a2782329 | |||
| 98dd329833 | |||
| 6213445bc4 | |||
| c5465bf9e2 | |||
| d881cb6e63 | |||
| 2e4faa4d50 | |||
| 8e1951f298 | |||
| 7efa924510 | |||
| febbc4fff0 | |||
| 39b2788b7e | |||
| a943dd3bdf | |||
| fedbff5971 | |||
| c2758e8321 | |||
| 8be5fe71df | |||
| 3f7ce41b9d | |||
| ad1cbedf00 | |||
| 83f54b5074 | |||
| a83928fd8c | |||
| ec55efd322 | |||
| 8c3709f92a | |||
| 207dbf1071 | |||
| 62c118e501 | |||
| 65dca13b42 | |||
| 3187cbdfe2 | |||
| 8c701d55c1 | |||
| f585489ff5 | |||
| 7113683ee0 | |||
| 1a0fc4bd5d | |||
| 40d1966e9a | |||
| a977200284 | |||
| b20fd3eba5 | |||
| b20daa1ac2 | |||
| b1a18459e7 | |||
| 6ba7c82f80 | |||
| ad7bb28b4c | |||
| fa7eda0889 | |||
| 00e02bf565 | |||
| 1ad66a71d8 | |||
| e60fa3d5e6 | |||
| 8407f6287f | |||
| 0833198d34 | |||
| 57347ae4d9 | |||
| 4876f18ba9 | |||
| a53ee42e13 | |||
| 12ccfc055a | |||
| feaa49d367 | |||
| 18f33b4a68 | |||
| f096b15dbd | |||
| cb5375258a | |||
| 076b5a39ad | |||
| f40ab41899 | |||
| e8fd5143bc | |||
| 31fb51de95 | |||
| 5d481eb79d | |||
| 1c90fe765d | |||
| 52ed8b81a6 | |||
| 0703a0a845 | |||
| 0c542d42aa | |||
| 966d1616c5 | |||
| 1720bd4aaa | |||
| df16378605 | |||
| 1438f0f373 | |||
| 766f3ba9ee | |||
| 5da4e6b424 | |||
| e382217e04 | |||
| 9db4e3fd87 | |||
| bb658be3b4 | |||
| 6579780dc9 | |||
| e56bc12788 | |||
| e88f309ea2 | |||
| 03bec27376 | |||
| 9d9008a3a2 | |||
| 5f6d462973 | |||
| a92b84bef4 | |||
| 477c530847 | |||
| c054d75717 | |||
| 15cd26f800 | |||
| 9465cffe79 | |||
| 00d2d06cbd | |||
| 8e4e702cb9 | |||
| 58311b37db | |||
| ad8dc09bee | |||
| 49be143588 | |||
| 0aea1d0177 | |||
| 6ea7721961 | |||
| b0cb997009 | |||
| 9dfca612b7 | |||
| 30ae743361 | |||
| d91f5f9df4 | |||
| 5ec457c76b | |||
| 2e670c4d03 | |||
| 3d32c33333 | |||
| 521f40a3d6 | |||
| 2bba5645c3 | |||
| bf0a5a80de | |||
| b37ef973de | |||
| 4c363f4073 | |||
| b8fa5fbbda | |||
| ac86f14a54 | |||
| 68b5697c8f | |||
| 09b0f0d0c8 | |||
| 98b418ff43 | |||
| 059bd0d371 | |||
| ef2a4df925 | |||
| 7578906310 | |||
| afe8905ac9 | |||
| ecc6091d1e | |||
| 3563ba80d0 | |||
| 09955be90f | |||
| dd4c19a15c | |||
| 07d5af1dde | |||
| 6f8595759e | |||
| 86da31033c | |||
| 974d103381 | |||
| 309758b994 | |||
| 965929d1eb | |||
| d47375a70e | |||
| d31b4ef5a8 | |||
| 7452c5df43 | |||
| 43d7b99905 | |||
| f90c48e881 | |||
| 2d7973520b | |||
| fd98ad95f6 | |||
| bfa8166223 | |||
| c42e336509 | |||
| 49d09a05d7 | |||
| 459794b863 | |||
| 039746112b | |||
| ac6d7ea5d4 | |||
| a89f00da19 | |||
| ff04ee7807 | |||
| 8b6e3abd23 | |||
| 1616f0ac90 | |||
| a20f39e847 | |||
| 334d3fb296 | |||
| eb2ca33e5a | |||
| 0ea4cba1ca | |||
| 1d13c8196e | |||
| ee6e1d4092 | |||
| c8679fca85 | |||
| f0ada1ba8c | |||
| b17682e50e | |||
| 5866acf565 | |||
| 6acf73a40f | |||
| 2f15d9676e | |||
| d78fcc48e5 | |||
| 4186723d37 | |||
| 17ee7b138d | |||
| aa84a27a5b | |||
| 438e598a4a | |||
| 174259155d | |||
| ba9339a50d | |||
| 65b4db5eca | |||
| 0fd82f1f3c | |||
| a3084456fd | |||
| 09b01af3fa | |||
| 9c8b72693e | |||
| c409e7b7ca | |||
| 2f05083cf0 | |||
| e934049dd4 | |||
|
|
94f796ebdb | ||
| 836ba269e3 | |||
| c8681096be | |||
| adeffe47ad | |||
| d95846a849 | |||
| af887c286f | |||
| 4ddf50162c | |||
| da819d8890 | |||
| 5ef5d57d30 | |||
| d7bddd825c | |||
| 15f46a87db | |||
| fc1ae4d57d | |||
| d0f3a120fd | |||
| c592a26346 | |||
| e68918c2e8 | |||
| 473f8a5a17 | |||
| 2f4b5bd9b2 | |||
| 23b9741adf | |||
| 5d8da08ce5 | |||
| a249aea703 | |||
| e432dd8208 | |||
| 8c385647dd | |||
| aaceecd5dc | |||
| 4b3f5a6b0c | |||
| d41e1d816a | |||
| a35974c9f5 | |||
| 9c456ba8f2 | |||
| c57884caee | |||
| cf7b62a3f9 | |||
| f2bf6d682a | |||
| a1fa8877f7 | |||
| 391f9bb808 | |||
| ef02dba8c5 | |||
| 2f4cfb68dc | |||
| 7009943106 | |||
| 0a76ccbdac | |||
| 32e4aa83b8 | |||
| 78c7064295 | |||
| 412a4bd9bb | |||
| b0bcb7febb | |||
| 51fbc34fb3 | |||
| 4e0f20eba0 | |||
| ff3fa19208 | |||
| 80057eef32 | |||
| a5186ff88d | |||
| f4ec21007b | |||
| ac8eab6e25 | |||
| 768716b064 | |||
| bea0dcc387 | |||
| a6691bcd3c | |||
| 40db74ce02 | |||
| c171e3c1ba | |||
| c251fe15d5 | |||
| dae8acb8a3 | |||
| f7cec99fa6 | |||
| be0e7db185 | |||
| 4aa26b85a0 | |||
| 9534d58d01 | |||
| 1668df0531 | |||
| d8e009c72b | |||
| d07c8679ed | |||
| 3d5b61f301 | |||
| 337f1634c0 | |||
| 72b09472d5 | |||
| 3261055871 | |||
| 34bb8e62ae | |||
| da7e29fbb7 | |||
| c4da47cedd | |||
| ab554539e3 | |||
| d43b35949e |
@@ -1,4 +1,3 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: LLVM
|
||||
# should be in line with IndentWidth
|
||||
@@ -13,8 +12,8 @@ AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: true
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
@@ -39,8 +38,8 @@ BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ColumnLimit: 140
|
||||
CommentPragmas: '^( IWYU pragma:| @suppress)'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ContinuationIndentWidth: 4
|
||||
@@ -76,13 +75,13 @@ PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Right
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParens: Never
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,5 +1,6 @@
|
||||
.DS_Store
|
||||
/*.il
|
||||
/.settings
|
||||
/avr-instr.html
|
||||
/blink.S
|
||||
/flash.*
|
||||
@@ -14,7 +15,6 @@
|
||||
/*.ods
|
||||
/build*/
|
||||
/*.logs
|
||||
language.settings.xml
|
||||
/*.gtkw
|
||||
/Debug wo LLVM/
|
||||
/*.txdb
|
||||
@@ -30,4 +30,5 @@ language.settings.xml
|
||||
/.gdbinit
|
||||
/*.out
|
||||
/dump.json
|
||||
/src-gen/
|
||||
/*.yaml
|
||||
/*.json
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "gen_input/CoreDSL-Instruction-Set-Description"]
|
||||
path = gen_input/CoreDSL-Instruction-Set-Description
|
||||
url = ../CoreDSL-Instruction-Set-Description.git
|
||||
1
.project
1
.project
@@ -23,6 +23,5 @@
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>org.eclipse.linuxtools.tmf.project.nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
|
||||
@@ -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
|
||||
332
CMakeLists.txt
332
CMakeLists.txt
@@ -1,123 +1,263 @@
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
project("riscv" VERSION 1.0.0)
|
||||
# ##############################################################################
|
||||
#
|
||||
# ##############################################################################
|
||||
project(dbt-rise-tgc VERSION 1.0.0)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(flink)
|
||||
|
||||
conan_basic_setup()
|
||||
|
||||
find_package(Boost COMPONENTS program_options system thread filesystem REQUIRED)
|
||||
if(WITH_LLVM)
|
||||
if(DEFINED ENV{LLVM_HOME})
|
||||
find_path (LLVM_DIR LLVM-Config.cmake $ENV{LLVM_HOME}/lib/cmake/llvm)
|
||||
endif(DEFINED ENV{LLVM_HOME})
|
||||
find_package(LLVM REQUIRED CONFIG)
|
||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
|
||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
|
||||
llvm_map_components_to_libnames(llvm_libs support core mcjit x86codegen x86asmparser)
|
||||
endif()
|
||||
|
||||
#Mac needed variables (adapt for your needs - http://www.cmake.org/Wiki/CMake_RPATH_handling#Mac_OS_X_and_the_RPATH)
|
||||
#set(CMAKE_MACOSX_RPATH ON)
|
||||
#set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
#set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
#set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
find_package(elfio QUIET)
|
||||
find_package(jsoncpp)
|
||||
find_package(Boost COMPONENTS coroutine REQUIRED)
|
||||
find_package(absl REQUIRED)
|
||||
|
||||
add_subdirectory(softfloat)
|
||||
|
||||
# library files
|
||||
FILE(GLOB RiscVSCHeaders ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*.h ${CMAKE_CURRENT_SOURCE_DIR}/incl/sysc/*/*.h)
|
||||
set(LIB_HEADERS ${RiscVSCHeaders} )
|
||||
set(LIB_SOURCES
|
||||
src/iss/tgf_b.cpp
|
||||
src/iss/tgf_c.cpp
|
||||
src/vm/fp_functions.cpp
|
||||
src/vm/tcc/vm_tgf_b.cpp
|
||||
src/vm/tcc/vm_tgf_c.cpp
|
||||
src/vm/interp/vm_tgf_b.cpp
|
||||
src/vm/interp/vm_tgf_c.cpp
|
||||
src/plugin/instruction_count.cpp
|
||||
src/plugin/cycle_estimate.cpp
|
||||
set(LIB_SOURCES
|
||||
src/iss/plugin/instruction_count.cpp
|
||||
src/iss/arch/tgc5c.cpp
|
||||
src/iss/mem/memory_if.cpp
|
||||
src/vm/interp/vm_tgc5c.cpp
|
||||
src/vm/fp_functions.cpp
|
||||
src/vm/vector_functions.cpp
|
||||
src/iss/debugger/csr_names.cpp
|
||||
src/iss/semihosting/semihosting.cpp
|
||||
)
|
||||
|
||||
if(WITH_TCC)
|
||||
list(APPEND LIB_SOURCES
|
||||
src/vm/tcc/vm_tgc5c.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
set(LIB_SOURCES ${LIB_SOURCES}
|
||||
src/vm/llvm/fp_impl.cpp
|
||||
src/vm/llvm/vm_tgf_b.cpp
|
||||
src/vm/llvm/vm_tgf_c.cpp
|
||||
)
|
||||
list(APPEND LIB_SOURCES
|
||||
src/vm/llvm/vm_tgc5c.cpp
|
||||
src/vm/llvm/fp_impl.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_ASMJIT)
|
||||
list(APPEND LIB_SOURCES
|
||||
src/vm/asmjit/vm_tgc5c.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# library files
|
||||
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_YAML_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/contrib/instr/*.yaml)
|
||||
list(APPEND LIB_SOURCES ${GEN_ISS_SOURCES} ${GEN_VM_SOURCES})
|
||||
|
||||
foreach(FILEPATH ${GEN_ISS_SOURCES})
|
||||
get_filename_component(CORE ${FILEPATH} NAME_WE)
|
||||
string(TOUPPER ${CORE} CORE)
|
||||
list(APPEND LIB_DEFINES CORE_${CORE})
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Core defines are ${LIB_DEFINES}")
|
||||
|
||||
if(WITH_LLVM)
|
||||
FILE(GLOB LLVM_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/llvm/vm_*.cpp)
|
||||
list(APPEND LIB_SOURCES ${LLVM_GEN_SOURCES})
|
||||
endif()
|
||||
|
||||
if(WITH_TCC)
|
||||
FILE(GLOB TCC_GEN_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/tcc/vm_*.cpp)
|
||||
list(APPEND LIB_SOURCES ${TCC_GEN_SOURCES})
|
||||
endif()
|
||||
|
||||
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
|
||||
src/iss/plugin/cycle_estimate.cpp
|
||||
src/iss/plugin/instruction_count.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Define the library
|
||||
add_library(riscv SHARED ${LIB_SOURCES})
|
||||
target_compile_options(riscv PRIVATE -Wno-shift-count-overflow)
|
||||
target_include_directories(riscv PUBLIC incl ../external/elfio)
|
||||
target_link_libraries(riscv PUBLIC softfloat scc-util jsoncpp)
|
||||
target_link_libraries(riscv PUBLIC -Wl,--whole-archive dbt-core -Wl,--no-whole-archive)
|
||||
set_target_properties(riscv PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
FRAMEWORK FALSE
|
||||
PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
|
||||
add_library(${PROJECT_NAME} SHARED ${LIB_SOURCES})
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE -Wno-shift-count-overflow)
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE /wd4293)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC src)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC src-gen)
|
||||
|
||||
target_force_link_libraries(${PROJECT_NAME} PRIVATE dbt-rise-core)
|
||||
|
||||
# only re-export the include paths
|
||||
get_target_property(DBT_CORE_INCL dbt-rise-core INTERFACE_INCLUDE_DIRECTORIES)
|
||||
target_include_directories(${PROJECT_NAME} INTERFACE ${DBT_CORE_INCL})
|
||||
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})
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC elfio::elfio softfloat scc-util Boost::coroutine abseil::abseil)
|
||||
|
||||
if(TARGET yaml-cpp::yaml-cpp)
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_PLUGINS)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC yaml-cpp::yaml-cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
FRAMEWORK FALSE
|
||||
)
|
||||
install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME}
|
||||
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # shared lib
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} # for mac
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} # headers for mac (note the different component -> different package)
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
||||
)
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss COMPONENT ${PROJECT_NAME}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # target directory
|
||||
FILES_MATCHING # install only matched files
|
||||
PATTERN "*.h" # select header files
|
||||
)
|
||||
install(FILES ${GEN_YAML_SOURCES} DESTINATION share/tgc-vp)
|
||||
|
||||
if(SystemC_FOUND)
|
||||
add_library(riscv_sc src/sysc/core_complex.cpp)
|
||||
target_compile_definitions(riscv_sc PUBLIC WITH_SYSTEMC)
|
||||
target_include_directories(riscv_sc PUBLIC ../incl ${SystemC_INCLUDE_DIRS} ${CCI_INCLUDE_DIRS})
|
||||
|
||||
if(SCV_FOUND)
|
||||
target_compile_definitions(riscv_sc PUBLIC WITH_SCV)
|
||||
target_include_directories(riscv_sc PUBLIC ${SCV_INCLUDE_DIRS})
|
||||
endif()
|
||||
target_link_libraries(riscv_sc PUBLIC riscv scc )
|
||||
if(WITH_LLVM)
|
||||
target_link_libraries(riscv_sc PUBLIC ${llvm_libs})
|
||||
endif()
|
||||
target_link_libraries(riscv_sc PUBLIC ${Boost_LIBRARIES} )
|
||||
set_target_properties(riscv_sc PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
FRAMEWORK FALSE
|
||||
PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
|
||||
)
|
||||
# ##############################################################################
|
||||
#
|
||||
# ##############################################################################
|
||||
set(CMAKE_INSTALL_RPATH $ORIGIN/../${CMAKE_INSTALL_LIBDIR})
|
||||
project(tgc-sim)
|
||||
find_package(Boost COMPONENTS program_options thread REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME} src/main.cpp)
|
||||
|
||||
if(TARGET ${CORE_NAME}_cpp)
|
||||
list(APPEND TGC_SOURCES ${${CORE_NAME}_OUTPUT_FILES})
|
||||
else()
|
||||
FILE(GLOB TGC_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src-gen/iss/arch/*.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src-gen/vm/interp/vm_*.cpp
|
||||
)
|
||||
list(APPEND TGC_SOURCES ${GEN_SOURCES})
|
||||
endif()
|
||||
|
||||
project("riscv-sim")
|
||||
add_executable(riscv-sim src/main.cpp)
|
||||
# This sets the include directory for the reference project. This is the -I flag in gcc.
|
||||
target_include_directories(riscv-sim PRIVATE ../external/libGIS)
|
||||
if(WITH_LLVM)
|
||||
target_compile_definitions(riscv-sim PRIVATE WITH_LLVM)
|
||||
target_link_libraries(riscv-sim PUBLIC ${llvm_libs})
|
||||
foreach(F IN LISTS TGC_SOURCES)
|
||||
if(${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
||||
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
||||
string(TOUPPER ${CORE_NAME_LC} CORE_NAME)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# if(WITH_LLVM)
|
||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_LLVM)
|
||||
# #target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||
# endif()
|
||||
# if(WITH_TCC)
|
||||
# target_compile_definitions(${PROJECT_NAME} PRIVATE WITH_TCC)
|
||||
# endif()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc fmt::fmt)
|
||||
|
||||
if(TARGET Boost::program_options)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::program_options)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${BOOST_program_options_LIBRARY})
|
||||
endif()
|
||||
# Links the target exe against the libraries
|
||||
target_link_libraries(riscv-sim riscv)
|
||||
target_link_libraries(riscv-sim jsoncpp)
|
||||
target_link_libraries(riscv-sim external)
|
||||
target_link_libraries(riscv-sim ${Boost_LIBRARIES} )
|
||||
if (Tcmalloc_FOUND)
|
||||
target_link_libraries(riscv-sim ${Tcmalloc_LIBRARIES})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_DL_LIBS})
|
||||
|
||||
if(Tcmalloc_FOUND)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC ${Tcmalloc_LIBRARIES})
|
||||
endif(Tcmalloc_FOUND)
|
||||
|
||||
install(TARGETS riscv riscv-sim
|
||||
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # static lib
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT libs # binaries
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # shared lib
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT libs # for mac
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} COMPONENT devel # headers for mac (note the different component -> different package)
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
||||
install(TARGETS tgc-sim
|
||||
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # shared lib
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} # for mac
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} # headers for mac (note the different component -> different package)
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
||||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
# ... CMake code to create tests ...
|
||||
add_test(NAME tgc-sim-interp
|
||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend interp)
|
||||
|
||||
if(WITH_TCC)
|
||||
add_test(NAME tgc-sim-tcc
|
||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend tcc)
|
||||
endif()
|
||||
|
||||
if(WITH_LLVM)
|
||||
add_test(NAME tgc-sim-llvm
|
||||
COMMAND tgc-sim -f ${CMAKE_BINARY_DIR}/../../Firmwares/hello-world/hello --backend llvm)
|
||||
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()
|
||||
|
||||
# ##############################################################################
|
||||
#
|
||||
# SYSTEM PACKAGING (RPM, TGZ, ...)
|
||||
# _____________________________________________________________________________
|
||||
# ##############################################################################
|
||||
if(TARGET scc-sysc)
|
||||
project(dbt-rise-tgc_sc VERSION 1.0.0)
|
||||
set(LIB_SOURCES
|
||||
src/sysc/core_complex.cpp
|
||||
src/sysc/register_tgc_c.cpp
|
||||
)
|
||||
FILE(GLOB GEN_SC_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src-gen/sysc/register_*.cpp)
|
||||
list(APPEND LIB_SOURCES ${GEN_SC_SOURCES})
|
||||
add_library(${PROJECT_NAME} ${LIB_SOURCES})
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC WITH_SYSTEMC)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||
|
||||
#include(CPackConfig)
|
||||
foreach(F IN LISTS TGC_SOURCES)
|
||||
if(${F} MATCHES ".*/arch/([^/]*)\.cpp")
|
||||
string(REGEX REPLACE ".*/([^/]*)\.cpp" "\\1" CORE_NAME_LC ${F})
|
||||
string(TOUPPER ${CORE_NAME_LC} CORE_NAME)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE CORE_${CORE_NAME})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# CMAKE PACKAGING (for other CMake projects to use this one easily)
|
||||
# _____________________________________________________________________________
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC dbt-rise-tgc scc-sysc)
|
||||
|
||||
#include(PackageConfigurator)
|
||||
# if(WITH_LLVM)
|
||||
# target_link_libraries(${PROJECT_NAME} PUBLIC ${llvm_libs})
|
||||
# endif()
|
||||
set(LIB_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/sysc/core_complex.h)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
FRAMEWORK FALSE
|
||||
PUBLIC_HEADER "${LIB_HEADERS}" # specify the public headers
|
||||
)
|
||||
install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME}
|
||||
EXPORT ${PROJECT_NAME}Targets # for downstream dependencies
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} # static lib
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} # binaries
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} # shared lib
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} # for mac
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sysc # headers for mac (note the different component -> different package)
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
|
||||
)
|
||||
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)
|
||||
|
||||
35
cmake/flink.cmake
Normal file
35
cmake/flink.cmake
Normal file
@@ -0,0 +1,35 @@
|
||||
# according to https://github.com/horance-liu/flink.cmake/tree/master
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
function(target_do_force_link_libraries target visibility lib)
|
||||
if(MSVC)
|
||||
target_link_libraries(${target} ${visibility} "/WHOLEARCHIVE:${lib}")
|
||||
elseif(APPLE)
|
||||
target_link_libraries(${target} ${visibility} -Wl,-force_load ${lib})
|
||||
else()
|
||||
target_link_libraries(${target} ${visibility} -Wl,--whole-archive ${lib} -Wl,--no-whole-archive)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(target_force_link_libraries target)
|
||||
cmake_parse_arguments(FLINK
|
||||
""
|
||||
""
|
||||
"PUBLIC;INTERFACE;PRIVATE"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
foreach(lib IN LISTS FLINK_PUBLIC)
|
||||
target_do_force_link_libraries(${target} PUBLIC ${lib})
|
||||
endforeach()
|
||||
|
||||
foreach(lib IN LISTS FLINK_INTERFACE)
|
||||
target_do_force_link_libraries(${target} INTERFACE ${lib})
|
||||
endforeach()
|
||||
|
||||
foreach(lib IN LISTS FLINK_PRIVATE)
|
||||
target_do_force_link_libraries(${target} PRIVATE ${lib})
|
||||
endforeach()
|
||||
endfunction()
|
||||
1
contrib/instr/.gitignore
vendored
Normal file
1
contrib/instr/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/*.yaml
|
||||
624
contrib/instr/TGC5C_instr.yaml
Normal file
624
contrib/instr/TGC5C_instr.yaml
Normal file
@@ -0,0 +1,624 @@
|
||||
|
||||
RVI:
|
||||
LUI:
|
||||
index: 0
|
||||
encoding: 0b00000000000000000000000000110111
|
||||
mask: 0b00000000000000000000000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
AUIPC:
|
||||
index: 1
|
||||
encoding: 0b00000000000000000000000000010111
|
||||
mask: 0b00000000000000000000000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
JAL:
|
||||
index: 2
|
||||
encoding: 0b00000000000000000000000001101111
|
||||
mask: 0b00000000000000000000000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
JALR:
|
||||
index: 3
|
||||
encoding: 0b00000000000000000000000001100111
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BEQ:
|
||||
index: 4
|
||||
encoding: 0b00000000000000000000000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BNE:
|
||||
index: 5
|
||||
encoding: 0b00000000000000000001000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BLT:
|
||||
index: 6
|
||||
encoding: 0b00000000000000000100000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BGE:
|
||||
index: 7
|
||||
encoding: 0b00000000000000000101000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BLTU:
|
||||
index: 8
|
||||
encoding: 0b00000000000000000110000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
BGEU:
|
||||
index: 9
|
||||
encoding: 0b00000000000000000111000001100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
LB:
|
||||
index: 10
|
||||
encoding: 0b00000000000000000000000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
LH:
|
||||
index: 11
|
||||
encoding: 0b00000000000000000001000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
LW:
|
||||
index: 12
|
||||
encoding: 0b00000000000000000010000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
LBU:
|
||||
index: 13
|
||||
encoding: 0b00000000000000000100000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
LHU:
|
||||
index: 14
|
||||
encoding: 0b00000000000000000101000000000011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SB:
|
||||
index: 15
|
||||
encoding: 0b00000000000000000000000000100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SH:
|
||||
index: 16
|
||||
encoding: 0b00000000000000000001000000100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SW:
|
||||
index: 17
|
||||
encoding: 0b00000000000000000010000000100011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
ADDI:
|
||||
index: 18
|
||||
encoding: 0b00000000000000000000000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLTI:
|
||||
index: 19
|
||||
encoding: 0b00000000000000000010000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLTIU:
|
||||
index: 20
|
||||
encoding: 0b00000000000000000011000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
XORI:
|
||||
index: 21
|
||||
encoding: 0b00000000000000000100000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
ORI:
|
||||
index: 22
|
||||
encoding: 0b00000000000000000110000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
ANDI:
|
||||
index: 23
|
||||
encoding: 0b00000000000000000111000000010011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLLI:
|
||||
index: 24
|
||||
encoding: 0b00000000000000000001000000010011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SRLI:
|
||||
index: 25
|
||||
encoding: 0b00000000000000000101000000010011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SRAI:
|
||||
index: 26
|
||||
encoding: 0b01000000000000000101000000010011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
ADD:
|
||||
index: 27
|
||||
encoding: 0b00000000000000000000000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SUB:
|
||||
index: 28
|
||||
encoding: 0b01000000000000000000000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLL:
|
||||
index: 29
|
||||
encoding: 0b00000000000000000001000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLT:
|
||||
index: 30
|
||||
encoding: 0b00000000000000000010000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SLTU:
|
||||
index: 31
|
||||
encoding: 0b00000000000000000011000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
XOR:
|
||||
index: 32
|
||||
encoding: 0b00000000000000000100000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SRL:
|
||||
index: 33
|
||||
encoding: 0b00000000000000000101000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
SRA:
|
||||
index: 34
|
||||
encoding: 0b01000000000000000101000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
OR:
|
||||
index: 35
|
||||
encoding: 0b00000000000000000110000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
AND:
|
||||
index: 36
|
||||
encoding: 0b00000000000000000111000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
FENCE:
|
||||
index: 37
|
||||
encoding: 0b00000000000000000000000000001111
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
ECALL:
|
||||
index: 38
|
||||
encoding: 0b00000000000000000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
EBREAK:
|
||||
index: 39
|
||||
encoding: 0b00000000000100000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
MRET:
|
||||
index: 40
|
||||
encoding: 0b00110000001000000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
attributes: [[name:no_cont]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
WFI:
|
||||
index: 41
|
||||
encoding: 0b00010000010100000000000001110011
|
||||
mask: 0b11111111111111111111111111111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
Zicsr:
|
||||
CSRRW:
|
||||
index: 42
|
||||
encoding: 0b00000000000000000001000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
CSRRS:
|
||||
index: 43
|
||||
encoding: 0b00000000000000000010000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
CSRRC:
|
||||
index: 44
|
||||
encoding: 0b00000000000000000011000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
CSRRWI:
|
||||
index: 45
|
||||
encoding: 0b00000000000000000101000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
CSRRSI:
|
||||
index: 46
|
||||
encoding: 0b00000000000000000110000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
CSRRCI:
|
||||
index: 47
|
||||
encoding: 0b00000000000000000111000001110011
|
||||
mask: 0b00000000000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
Zifencei:
|
||||
FENCE_I:
|
||||
index: 48
|
||||
encoding: 0b00000000000000000001000000001111
|
||||
mask: 0b00000000000000000111000001111111
|
||||
attributes: [[name:flush]]
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
RVM:
|
||||
MUL:
|
||||
index: 49
|
||||
encoding: 0b00000010000000000000000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
MULH:
|
||||
index: 50
|
||||
encoding: 0b00000010000000000001000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
MULHSU:
|
||||
index: 51
|
||||
encoding: 0b00000010000000000010000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
MULHU:
|
||||
index: 52
|
||||
encoding: 0b00000010000000000011000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
DIV:
|
||||
index: 53
|
||||
encoding: 0b00000010000000000100000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
DIVU:
|
||||
index: 54
|
||||
encoding: 0b00000010000000000101000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
REM:
|
||||
index: 55
|
||||
encoding: 0b00000010000000000110000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
REMU:
|
||||
index: 56
|
||||
encoding: 0b00000010000000000111000000110011
|
||||
mask: 0b11111110000000000111000001111111
|
||||
size: 32
|
||||
branch: false
|
||||
delay: 1
|
||||
Zca:
|
||||
C__ADDI4SPN:
|
||||
index: 57
|
||||
encoding: 0b0000000000000000
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__LW:
|
||||
index: 58
|
||||
encoding: 0b0100000000000000
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__SW:
|
||||
index: 59
|
||||
encoding: 0b1100000000000000
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__ADDI:
|
||||
index: 60
|
||||
encoding: 0b0000000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__NOP:
|
||||
index: 61
|
||||
encoding: 0b0000000000000001
|
||||
mask: 0b1110111110000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__JAL:
|
||||
index: 62
|
||||
encoding: 0b0010000000000001
|
||||
mask: 0b1110000000000011
|
||||
attributes: [[name:enable, value:1]]
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
C__LI:
|
||||
index: 63
|
||||
encoding: 0b0100000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__LUI:
|
||||
index: 64
|
||||
encoding: 0b0110000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__ADDI16SP:
|
||||
index: 65
|
||||
encoding: 0b0110000100000001
|
||||
mask: 0b1110111110000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
__reserved_clui:
|
||||
index: 66
|
||||
encoding: 0b0110000000000001
|
||||
mask: 0b1111000001111111
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__SRLI:
|
||||
index: 67
|
||||
encoding: 0b1000000000000001
|
||||
mask: 0b1111110000000011
|
||||
attributes: [[name:enable, value:1]]
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__SRAI:
|
||||
index: 68
|
||||
encoding: 0b1000010000000001
|
||||
mask: 0b1111110000000011
|
||||
attributes: [[name:enable, value:1]]
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__ANDI:
|
||||
index: 69
|
||||
encoding: 0b1000100000000001
|
||||
mask: 0b1110110000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__SUB:
|
||||
index: 70
|
||||
encoding: 0b1000110000000001
|
||||
mask: 0b1111110001100011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__XOR:
|
||||
index: 71
|
||||
encoding: 0b1000110000100001
|
||||
mask: 0b1111110001100011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__OR:
|
||||
index: 72
|
||||
encoding: 0b1000110001000001
|
||||
mask: 0b1111110001100011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__AND:
|
||||
index: 73
|
||||
encoding: 0b1000110001100001
|
||||
mask: 0b1111110001100011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__J:
|
||||
index: 74
|
||||
encoding: 0b1010000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
C__BEQZ:
|
||||
index: 75
|
||||
encoding: 0b1100000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
C__BNEZ:
|
||||
index: 76
|
||||
encoding: 0b1110000000000001
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: true
|
||||
delay: [1,1]
|
||||
C__SLLI:
|
||||
index: 77
|
||||
encoding: 0b0000000000000010
|
||||
mask: 0b1111000000000011
|
||||
attributes: [[name:enable, value:1]]
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__LWSP:
|
||||
index: 78
|
||||
encoding: 0b0100000000000010
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__MV:
|
||||
index: 79
|
||||
encoding: 0b1000000000000010
|
||||
mask: 0b1111000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__JR:
|
||||
index: 80
|
||||
encoding: 0b1000000000000010
|
||||
mask: 0b1111000001111111
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
__reserved_cmv:
|
||||
index: 81
|
||||
encoding: 0b1000000000000010
|
||||
mask: 0b1111111111111111
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__ADD:
|
||||
index: 82
|
||||
encoding: 0b1001000000000010
|
||||
mask: 0b1111000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__JALR:
|
||||
index: 83
|
||||
encoding: 0b1001000000000010
|
||||
mask: 0b1111000001111111
|
||||
size: 16
|
||||
branch: true
|
||||
delay: 1
|
||||
C__EBREAK:
|
||||
index: 84
|
||||
encoding: 0b1001000000000010
|
||||
mask: 0b1111111111111111
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
C__SWSP:
|
||||
index: 85
|
||||
encoding: 0b1100000000000010
|
||||
mask: 0b1110000000000011
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
DII:
|
||||
index: 86
|
||||
encoding: 0b0000000000000000
|
||||
mask: 0b1111111111111111
|
||||
size: 16
|
||||
branch: false
|
||||
delay: 1
|
||||
|
||||
650
contrib/instr/TGC5C_slow.yaml
Normal file
650
contrib/instr/TGC5C_slow.yaml
Normal file
@@ -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
|
||||
3
contrib/pa/.gitignore
vendored
Normal file
3
contrib/pa/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/results
|
||||
/cwr
|
||||
/*.xml
|
||||
43
contrib/pa/README.md
Normal file
43
contrib/pa/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Notes
|
||||
|
||||
* requires conan version 1.59
|
||||
* requires decent cmake version 3.23
|
||||
|
||||
Setup for tcsh:
|
||||
|
||||
```
|
||||
git clone --recursive -b develop https://git.minres.com/TGFS/TGC-ISS.git
|
||||
cd TGC-ISS/
|
||||
setenv TGFS_INSTALL_ROOT `pwd`/install
|
||||
setenv COWAREHOME <your SNPS PA installation>
|
||||
setenv SNPSLMD_LICENSE_FILE <your SNPS PA license file>
|
||||
source $COWAREHOME/SLS/linux/setup.csh pae
|
||||
setenv SNPS_ENABLE_MEM_ON_DEMAND_IN_GENERIC_MEM 1
|
||||
setenv PATH $COWAREHOME/common/bin/:${PATH}
|
||||
setenv CC $COWAREHOME/SLS/linux/common/bin/gcc
|
||||
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 \
|
||||
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
||||
cmake --build build/PA --target install -j16
|
||||
cd dbt-rise-tgc/contrib/pa
|
||||
# import the TGC core itself
|
||||
pct tgc_import_tb.tcl
|
||||
```
|
||||
|
||||
Setup for bash:
|
||||
|
||||
```
|
||||
git clone --recursive -b develop https://git.minres.com/TGFS/TGC-ISS.git
|
||||
cd TGC-ISS/
|
||||
export TGFS_INSTALL_ROOT `pwd`/install
|
||||
module load tools/pa/T-2022.06
|
||||
export SNPS_ENABLE_MEM_ON_DEMAND_IN_GENERIC_MEM=1
|
||||
export CC=$COWAREHOME/SLS/linux/common/bin/gcc
|
||||
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 \
|
||||
-DCODEGEN=OFF -DCMAKE_INSTALL_PREFIX=${TGFS_INSTALL_ROOT}
|
||||
cmake --build build/PA --target install -j16
|
||||
cd dbt-rise-tgc/contrib/pa
|
||||
# import the TGC core itself
|
||||
pct tgc_import_tb.tcl
|
||||
```
|
||||
30
contrib/pa/build.tcl
Normal file
30
contrib/pa/build.tcl
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace eval Specification {
|
||||
proc buildproc { args } {
|
||||
global env
|
||||
variable installDir
|
||||
variable compiler
|
||||
variable compiler [::scsh::get_backend_compiler]
|
||||
# set target $machine
|
||||
set target [::scsh::machine]
|
||||
set linkerOptions ""
|
||||
set preprocessorOptions ""
|
||||
set libversion $compiler
|
||||
switch -exact -- $target {
|
||||
"linux" {
|
||||
set install_dir $::env(TGFS_INSTALL_ROOT)
|
||||
set incldir "${install_dir}/include"
|
||||
set libdir "${install_dir}/lib64"
|
||||
set preprocessorOptions [concat $preprocessorOptions "-I${incldir}"]
|
||||
# Set the Linker paths.
|
||||
set linkerOptions [concat $linkerOptions "-Wl,-rpath,${libdir} -L${libdir} -ldbt-rise-tgc_sc -lscc-sysc"]
|
||||
}
|
||||
default {
|
||||
puts stderr "ERROR: \"$target\" is not supported, [::scsh::version]"
|
||||
return
|
||||
}
|
||||
}
|
||||
::scsh::cwr_append_ipsimbld_opts preprocessor "$preprocessorOptions"
|
||||
::scsh::cwr_append_ipsimbld_opts linker "$linkerOptions"
|
||||
}
|
||||
::scsh::add_build_callback [namespace current]::buildproc
|
||||
}
|
||||
2092
contrib/pa/hello.dis
Normal file
2092
contrib/pa/hello.dis
Normal file
File diff suppressed because it is too large
Load Diff
BIN
contrib/pa/hello.elf
Executable file
BIN
contrib/pa/hello.elf
Executable file
Binary file not shown.
BIN
contrib/pa/minres.png
Executable file
BIN
contrib/pa/minres.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
4
contrib/pa/tgc_import.cc
Normal file
4
contrib/pa/tgc_import.cc
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
#include "sysc/core_complex.h"
|
||||
|
||||
void modules() { sysc::tgfs::core_complex i_core_complex("core_complex"); }
|
||||
50
contrib/pa/tgc_import.tcl
Normal file
50
contrib/pa/tgc_import.tcl
Normal file
@@ -0,0 +1,50 @@
|
||||
#############################################################################
|
||||
#
|
||||
#############################################################################
|
||||
proc getScriptDirectory {} {
|
||||
set dispScriptFile [file normalize [info script]]
|
||||
set scriptFolder [file dirname $dispScriptFile]
|
||||
return $scriptFolder
|
||||
}
|
||||
set hardware /HARDWARE/HW/HW
|
||||
|
||||
set scriptDir [getScriptDirectory]
|
||||
set top_design_name core_complex
|
||||
set encap_name sysc::tgfs::${top_design_name}
|
||||
set clocks clk_i
|
||||
set resets rst_i
|
||||
set model_prefix "i_"
|
||||
set model_postfix ""
|
||||
|
||||
::pct::new_project
|
||||
::pct::open_library TLM2_PL
|
||||
::pct::clear_systemc_defines
|
||||
::pct::clear_systemc_include_path
|
||||
::pct::add_to_systemc_include_path $::env(TGFS_INSTALL_ROOT)/include
|
||||
::pct::set_import_protocol_generation_flag false
|
||||
::pct::set_update_existing_encaps_flag true
|
||||
::pct::set_dynamic_port_arrays_flag true
|
||||
::pct::set_import_scml_properties_flag true
|
||||
::pct::set_import_encap_prop_as_extra_prop_flag true
|
||||
::pct::load_modules --set-category modules ${scriptDir}/tgc_import.cc
|
||||
|
||||
# Set Port Protocols correctly
|
||||
set block ${top_design_name}
|
||||
foreach clock ${clocks} {
|
||||
::pct::set_block_port_protocol --set-category SYSTEM_LIBRARY:$block/${clock} SYSTEM_LIBRARY:CLOCK
|
||||
}
|
||||
foreach reset ${resets} {
|
||||
::pct::set_block_port_protocol --set-category SYSTEM_LIBRARY:$block/${reset} SYSTEM_LIBRARY:RESET
|
||||
}
|
||||
#::pct::set_encap_port_array_size SYSTEM_LIBRARY:$block/local_irq_i 16
|
||||
|
||||
# Set compile settings and look
|
||||
set block SYSTEM_LIBRARY:${top_design_name}
|
||||
::pct::set_encap_build_script $block/${encap_name} $scriptDir/build.tcl
|
||||
::pct::set_background_color_rgb $block 255 255 255 255
|
||||
::pct::create_instance SYSTEM_LIBRARY:${top_design_name} ${hardware} ${model_prefix}${top_design_name}${model_postfix} ${encap_name} ${encap_name}()
|
||||
::pct::set_bounds i_${top_design_name} 200 300 100 400
|
||||
::pct::set_image i_${top_design_name} "$scriptDir/minres.png" center center false true
|
||||
|
||||
# export the result as component
|
||||
::pct::export_system_library ${top_design_name} ${top_design_name}.xml
|
||||
71
contrib/pa/tgc_import_tb.tcl
Normal file
71
contrib/pa/tgc_import_tb.tcl
Normal file
@@ -0,0 +1,71 @@
|
||||
source tgc_import.tcl
|
||||
set hardware /HARDWARE/HW/HW
|
||||
set FW_name ${scriptDir}/hello.elf
|
||||
|
||||
puts "instantiate testbench elements"
|
||||
::paultra::add_hw_instance GenericIPlib:Memory_Generic -inst_name i_Memory_Generic
|
||||
::pct::set_param_value i_Memory_Generic/MEM:protocol {Protocol Common Parameters} address_width 30
|
||||
::pct::set_param_value i_Memory_Generic {Scml Properties} /timing/LT/clock_period_in_ns 1
|
||||
::pct::set_param_value i_Memory_Generic {Scml Properties} /timing/read/cmd_accept_cycles 1
|
||||
::pct::set_param_value i_Memory_Generic {Scml Properties} /timing/write/cmd_accept_cycles 1
|
||||
::pct::set_bounds i_Memory_Generic 1000 300 100 100
|
||||
|
||||
::paultra::add_hw_instance Bus:Bus -inst_name i_Bus
|
||||
::BLWizard::generateFramework i_Bus SBLTLM2FT * {} \
|
||||
{ common_configuration:BackBone:/advanced/num_resources_per_target:1 }
|
||||
::pct::set_bounds i_Bus 700 300 100 400
|
||||
::pct::create_connection C_ibus i_core_complex/ibus i_Bus/i_core_complex_ibus
|
||||
::pct::set_location_on_owner i_Bus/i_core_complex_ibus 10
|
||||
::pct::create_connection C_dbus i_core_complex/dbus i_Bus/i_core_complex_dbus
|
||||
::pct::set_location_on_owner i_Bus/i_core_complex_dbus 10
|
||||
::pct::create_connection C_mem i_Bus/i_Memory_Generic_MEM i_Memory_Generic/MEM
|
||||
|
||||
puts "instantiating clock manager"
|
||||
set clock "Clk"
|
||||
::hw::create_hw_instance "" GenericIPlib:ClockGenerator ${clock}_clock
|
||||
::pct::set_bounds ${clock}_clock 100 100 100 100
|
||||
::pct::set_param_value $hardware/${clock}_clock {Constructor Arguments} period 1000
|
||||
::pct::set_param_value $hardware/${clock}_clock {Constructor Arguments} period_unit sc_core::SC_PS
|
||||
|
||||
puts "instantiating reset manager"
|
||||
set reset "Rst"
|
||||
::hw::create_hw_instance "" GenericIPlib:ResetGenerator ${reset}_reset
|
||||
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} start_time 0
|
||||
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} start_time_unit sc_core::SC_PS
|
||||
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} duration 10000
|
||||
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} duration_unit sc_core::SC_PS
|
||||
::pct::set_param_value $hardware/${reset}_reset {Constructor Arguments} active_level true
|
||||
::pct::set_bounds ${reset}_reset 300 100 100 100
|
||||
|
||||
puts "connecting reset/clock"
|
||||
::pct::create_connection C_clk . Clk_clock/CLK i_core_complex/clk_i
|
||||
::pct::add_ports_to_connection C_clk i_Bus/Clk
|
||||
::pct::add_ports_to_connection C_clk i_Memory_Generic/CLK
|
||||
::pct::create_connection C_rst . Rst_reset/RST i_core_complex/rst_i
|
||||
::pct::add_ports_to_connection C_rst i_Bus/Rst
|
||||
|
||||
puts "setting parameters for DBT-RISE-TGC/Bus and memory components"
|
||||
::pct::set_param_value $hardware/i_${top_design_name} {Extra properties} elf_file ${FW_name}
|
||||
::pct::set_address $hardware/i_${top_design_name}/ibus:i_Memory_Generic/MEM 0x0
|
||||
::pct::set_address $hardware/i_${top_design_name}/dbus:i_Memory_Generic/MEM 0x0
|
||||
::BLWizard::updateFramework i_Bus {} { common_configuration:BackBone:/advanced/num_resources_per_target:1 }
|
||||
|
||||
::pct::set_main_configuration Default {{#include <scc/report.h>} {::scc::init_logging(::scc::LogConfig().logLevel(::scc::log::INFO).coloredOutput(false).logAsync(false));} {} {} {}}
|
||||
::pct::set_main_configuration Debug {{#include <scc/report.h>} {::scc::init_logging(::scc::LogConfig().logLevel(::scc::log::DEBUG).coloredOutput(false).logAsync(false));} {} {} {}}
|
||||
::pct::create_simulation_build_config Debug
|
||||
::pct::set_simulation_build_project_setting Debug "Main Configuration" Default
|
||||
# add build settings and save design for next steps
|
||||
#::pct::set_simulation_build_project_setting "Debug" "Linker Flags" "-Wl,-z,muldefs $::env(VERILATOR_ROOT)/include/verilated.cpp $::env(VERILATOR_ROOT)/include/verilated_vcd_sc.cpp $::env(VERILATOR_ROOT)/include/verilated_vcd_c.cpp"
|
||||
#::pct::set_simulation_build_project_setting "Debug" "Include Paths" $::env(VERILATOR_ROOT)/include/
|
||||
|
||||
#::simulation::set_simulation_property Simulation [list run_for_duration:200ns results_dir:results/test_0 "TLM Port Trace:true"]
|
||||
#::simulation::run_simulation Simulation
|
||||
|
||||
#::pct::set_simulation_build_project_setting Debug {Export Type} {STATIC NETLIST}
|
||||
#::pct::set_simulation_build_project_setting Debug {Encapsulated Netlist} false
|
||||
#::pct::export_system "export"
|
||||
#::cd "export"
|
||||
#::scsh::open-project
|
||||
#::scsh::build
|
||||
#::scsh::elab sim
|
||||
::pct::save_system testbench.xml
|
||||
1
gen_input/.gitignore
vendored
1
gen_input/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
/src-gen/
|
||||
/CoreDSL-Instruction-Set-Description
|
||||
|
||||
Submodule gen_input/CoreDSL-Instruction-Set-Description deleted from 3bb3763e92
13
gen_input/TGC5C.core_desc
Normal file
13
gen_input/TGC5C.core_desc
Normal file
@@ -0,0 +1,13 @@
|
||||
import "ISA/RVI.core_desc"
|
||||
import "ISA/RVM.core_desc"
|
||||
import "ISA/RVC.core_desc"
|
||||
|
||||
Core TGC5C provides RV32I, Zicsr, Zifencei, RV32M, RV32IC {
|
||||
architectural_state {
|
||||
XLEN=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
unsigned int MISA_VAL = 0b01000000000000000001000100000100;
|
||||
unsigned int MARCHID_VAL = 0x80000003;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import "CoreDSL-Instruction-Set-Description/RV32I.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVM.core_desc"
|
||||
import "CoreDSL-Instruction-Set-Description/RVC.core_desc"
|
||||
|
||||
Core TGF_B provides RV32I {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
PCLEN:=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000000000000000100000000;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core TGF_C provides RV32I, RV32M, RV32IC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
PCLEN:=32;
|
||||
MUL_LEN:=64;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000000000001000100000100;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
import "RV32I.core_desc"
|
||||
import "RV64I.core_desc"
|
||||
import "RVM.core_desc"
|
||||
import "RVA.core_desc"
|
||||
import "RVC.core_desc"
|
||||
import "RVF.core_desc"
|
||||
import "RVD.core_desc"
|
||||
|
||||
|
||||
Core MNRV32 provides RV32I, RV32IC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
PCLEN:=32;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000101000001000100000101;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core RV32IMAC provides RV32I, RV32M, RV32A, RV32IC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
PCLEN:=32;
|
||||
MUL_LEN:=64;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000101000001000100000101;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core RV32GC provides RV32I, RV32M, RV32A, RV32F, RV32D, RV32IC, RV32FC, RV32DC {
|
||||
constants {
|
||||
XLEN:=32;
|
||||
FLEN:=64;
|
||||
PCLEN:=32;
|
||||
MUL_LEN:=64;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000101000001000100101101;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core RV64I provides RV64I {
|
||||
constants {
|
||||
XLEN:=64;
|
||||
PCLEN:=64;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b10000000000001000000000100000000;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
Core RV64GC provides RV64I, RV64M, RV64A, RV64F, RV64D, RV32FC, RV32DC, RV64IC {
|
||||
constants {
|
||||
XLEN:=64;
|
||||
FLEN:=64;
|
||||
PCLEN:=64;
|
||||
MUL_LEN:=128;
|
||||
// definitions for the architecture wrapper
|
||||
// XL ZYXWVUTSRQPONMLKJIHGFEDCBA
|
||||
MISA_VAL:=0b01000000000101000001000100101101;
|
||||
PGSIZE := 0x1000; //1 << 12;
|
||||
PGMASK := 0xfff; //PGSIZE-1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2017, 2018 MINRES Technologies GmbH
|
||||
* Copyright (C) 2024 MINRES Technologies GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -29,71 +29,41 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
<%
|
||||
import com.minres.coredsl.coreDsl.Register
|
||||
import com.minres.coredsl.coreDsl.RegisterFile
|
||||
import com.minres.coredsl.coreDsl.RegisterAlias
|
||||
def getOriginalName(reg){
|
||||
if( reg.original instanceof RegisterFile) {
|
||||
if( reg.index != null ) {
|
||||
return reg.original.name+generator.generateHostCode(reg.index)
|
||||
} else {
|
||||
return reg.original.name
|
||||
}
|
||||
} else if(reg.original instanceof Register){
|
||||
return reg.original.name
|
||||
}
|
||||
}
|
||||
def getRegisterNames(){
|
||||
def regNames = []
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{
|
||||
regNames+=reg.name.toLowerCase()+it
|
||||
}
|
||||
} else if(reg instanceof Register){
|
||||
regNames+=reg.name.toLowerCase()
|
||||
}
|
||||
}
|
||||
return regNames
|
||||
}
|
||||
def getRegisterAliasNames(){
|
||||
def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
|
||||
return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
|
||||
} else if(reg instanceof Register){
|
||||
regMap[reg.name]?:reg.name.toLowerCase()
|
||||
}
|
||||
}.flatten()
|
||||
<%
|
||||
def getRegisterSizes(){
|
||||
def regs = registers.collect{it.size}
|
||||
regs[-1]=64 // correct for NEXT_PC
|
||||
regs+=[32,32, 64, 64, 64, 32, 32] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION, LAST_BRANCH
|
||||
return regs
|
||||
}
|
||||
%>
|
||||
// clang-format off
|
||||
#include "${coreDef.name.toLowerCase()}.h"
|
||||
#include "util/ities.h"
|
||||
#include <util/logging.h>
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
|
||||
using namespace iss::arch;
|
||||
|
||||
constexpr std::array<const char*, ${getRegisterNames().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
|
||||
constexpr std::array<const char*, ${getRegisterAliasNames().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
|
||||
constexpr std::array<const uint32_t, ${regSizes.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
|
||||
constexpr std::array<const uint32_t, ${regOffsets.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
|
||||
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 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;
|
||||
|
||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
|
||||
reg.icount = 0;
|
||||
}
|
||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() = default;
|
||||
|
||||
${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default;
|
||||
|
||||
void ${coreDef.name.toLowerCase()}::reset(uint64_t address) {
|
||||
for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0));
|
||||
auto base_ptr = reinterpret_cast<traits<${coreDef.name.toLowerCase()}>::reg_t*>(get_regs_base_ptr());
|
||||
for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i)
|
||||
*(base_ptr+i)=0;
|
||||
reg.PC=address;
|
||||
reg.NEXT_PC=reg.PC;
|
||||
reg.PRIV=0x3;
|
||||
reg.trap_state=0;
|
||||
reg.machine_state=0x3;
|
||||
reg.icount=0;
|
||||
}
|
||||
|
||||
@@ -101,7 +71,7 @@ uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() {
|
||||
return reinterpret_cast<uint8_t*>(®);
|
||||
}
|
||||
|
||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
${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);
|
||||
}
|
||||
|
||||
// clang-format on
|
||||
206
gen_input/templates/CORENAME.h.gtl
Normal file
206
gen_input/templates/CORENAME.h.gtl
Normal file
@@ -0,0 +1,206 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
<%
|
||||
def nativeSize(int size){
|
||||
if(size<=8) return 8;
|
||||
if(size<=16) return 16;
|
||||
if(size<=32) return 32;
|
||||
if(size<=64) return 64;
|
||||
if(size<=128) return 128;
|
||||
if(size<=256) return 256;
|
||||
if(size<=512) return 512;
|
||||
if(size<=1024) return 1024;
|
||||
if(size<=2048) return 2048;
|
||||
if(size<=4096) return 4096;
|
||||
throw new IllegalArgumentException("Unsupported size in nativeSize in CORENAME.h.gtl");
|
||||
}
|
||||
def getRegisterSizes(){
|
||||
def regs = registers.collect{nativeSize(it.size)}
|
||||
regs+=[32,32, 64, 64, 64, 32, 32] // append TRAP_STATE, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION, LAST_BRANCH
|
||||
return regs
|
||||
}
|
||||
def getRegisterOffsets(){
|
||||
def offset = 0
|
||||
def offsets = []
|
||||
getRegisterSizes().each { size ->
|
||||
offsets<<offset
|
||||
offset+=size/8
|
||||
}
|
||||
return offsets
|
||||
}
|
||||
|
||||
def getCString(def val){
|
||||
return val.toString()+'ULL'
|
||||
}
|
||||
%>
|
||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||
#define _${coreDef.name.toUpperCase()}_H_
|
||||
// clang-format off
|
||||
#include <array>
|
||||
#include <iss/arch/traits.h>
|
||||
#include <iss/arch_if.h>
|
||||
#include <iss/vm_if.h>
|
||||
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
struct ${coreDef.name.toLowerCase()};
|
||||
|
||||
template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||
|
||||
constexpr static char const* const core_type = "${coreDef.name}";
|
||||
|
||||
static constexpr std::array<const char*, ${registers.size()}> reg_names{
|
||||
{"${registers.collect{it.name.toLowerCase()}.join('", "')}"}};
|
||||
|
||||
static constexpr std::array<const char*, ${registers.size()}> reg_aliases{
|
||||
{"${registers.collect{it.alias.toLowerCase()}.join('", "')}"}};
|
||||
|
||||
enum constants {${constants.collect{c -> c.name+"="+getCString(c.value)}.join(', ')}};
|
||||
|
||||
constexpr static unsigned FP_REGS_SIZE = ${constants.find {it.name=='FLEN'}?.value?:0};
|
||||
constexpr static unsigned V_REGS_SIZE = ${constants.find {it.name=='VLEN'}?.value?:0};
|
||||
|
||||
|
||||
enum reg_e {
|
||||
${registers.collect{it.name}.join(', ')}, NUM_REGS, TRAP_STATE=NUM_REGS, PENDING_TRAP, ICOUNT, CYCLE, INSTRET, INSTRUCTION, LAST_BRANCH
|
||||
};
|
||||
|
||||
using reg_t = uint${addrDataWidth}_t;
|
||||
|
||||
using addr_t = uint${addrDataWidth}_t;
|
||||
|
||||
using code_word_t = uint${addrDataWidth}_t; //TODO: check removal
|
||||
|
||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
static constexpr std::array<const uint32_t, ${getRegisterSizes().size()}> reg_bit_widths{
|
||||
{${getRegisterSizes().join(',')}}};
|
||||
|
||||
static constexpr std::array<const uint32_t, ${getRegisterOffsets().size()}> reg_byte_offsets{
|
||||
{${getRegisterOffsets().join(',')}}};
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
enum sreg_flag_e { FLAGS };
|
||||
|
||||
enum mem_type_e { ${spaces.collect{it.name}.join(', ')}, IMEM = MEM };
|
||||
|
||||
enum class opcode_e {<%instructions.eachWithIndex{instr, index -> %>
|
||||
${instr.instruction.name} = ${index},<%}%>
|
||||
MAX_OPCODE
|
||||
};
|
||||
};
|
||||
|
||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||
|
||||
using virt_addr_t = typename traits<${coreDef.name.toLowerCase()}>::virt_addr_t;
|
||||
using phys_addr_t = typename traits<${coreDef.name.toLowerCase()}>::phys_addr_t;
|
||||
using reg_t = typename traits<${coreDef.name.toLowerCase()}>::reg_t;
|
||||
using addr_t = typename traits<${coreDef.name.toLowerCase()}>::addr_t;
|
||||
|
||||
${coreDef.name.toLowerCase()}();
|
||||
~${coreDef.name.toLowerCase()}();
|
||||
|
||||
void reset(uint64_t address=0) override;
|
||||
|
||||
uint8_t* get_regs_base_ptr() override;
|
||||
|
||||
inline bool should_stop() { return interrupt_sim; }
|
||||
|
||||
inline uint64_t stop_code() { return interrupt_sim; }
|
||||
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ${coreDef.name}_regs {<%
|
||||
registers.each { reg -> if(reg.size>64) {%>
|
||||
uint8_t ${reg.name}[${reg.size/8}] = {0};<%
|
||||
}else if(reg.size>0) {%>
|
||||
uint${nativeSize(reg.size)}_t ${reg.name} = 0;<%
|
||||
}}%>
|
||||
uint32_t trap_state = 0, pending_trap = 0;
|
||||
uint64_t icount = 0; // counts number of instructions undisturbed
|
||||
uint64_t cycle = 0; // counts number of cycles, in functional mode equals icount
|
||||
uint64_t instret = 0; // counts number of instructions, can be reset via CSR write
|
||||
uint32_t instruction = 0; // holds op code of currently executed instruction
|
||||
uint32_t last_branch = 0; // indicates if last branch was taken
|
||||
} reg;
|
||||
#pragma pack(pop)
|
||||
std::array<address_type, 4> addr_mode;
|
||||
|
||||
uint64_t interrupt_sim=0;
|
||||
<%
|
||||
def fcsr = registers.find {it.name=='FCSR'}
|
||||
if(fcsr != null) {%>
|
||||
uint${fcsr.size}_t get_fcsr(){return reg.FCSR;}
|
||||
void set_fcsr(uint${fcsr.size}_t val){reg.FCSR = val;}
|
||||
<%} else { %>
|
||||
uint32_t get_fcsr(){return 0;}
|
||||
void set_fcsr(uint32_t val){}
|
||||
<%}
|
||||
def vstart = registers.find {it.name=='vstart'}
|
||||
def vl = registers.find {it.name=='vl'}
|
||||
def vtype = registers.find {it.name=='vtype'}
|
||||
def vxsat = registers.find {it.name=='vxsat'}
|
||||
def vxrm = registers.find {it.name=='vxrm'}
|
||||
|
||||
if(vtype != null) {%>
|
||||
uint${vstart.size}_t get_vstart(){return reg.vstart;}
|
||||
void set_vstart(uint${vstart.size}_t val){reg.vstart = val;}
|
||||
uint${vl.size}_t get_vl(){return reg.vl;}
|
||||
uint${vtype.size}_t get_vtype(){return reg.vtype;}
|
||||
uint${vxsat.size}_t get_vxsat(){return reg.vxsat;}
|
||||
void set_vxsat(uint${vxsat.size}_t val){reg.vxsat = val;}
|
||||
uint${vxrm.size}_t get_vxrm(){return reg.vxrm;}
|
||||
void set_vxrm(uint${vxrm.size}_t val){reg.vxrm = val;}
|
||||
<%} else { %>
|
||||
uint32_t get_vstart(){return 0;}
|
||||
void set_vstart(uint32_t val){}
|
||||
uint32_t get_vl(){return 0;}
|
||||
uint32_t get_vtype(){return 0;}
|
||||
uint32_t get_vxsat(){return 0;}
|
||||
void set_vxsat(uint32_t val){}
|
||||
uint32_t get_vxrm(){return 0;}
|
||||
void set_vxrm(uint32_t val){}
|
||||
<%}%>
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
||||
// clang-format on
|
||||
12
gen_input/templates/CORENAME_cyles.txt.gtl
Normal file
12
gen_input/templates/CORENAME_cyles.txt.gtl
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","}
|
||||
{
|
||||
"name" : "${instr.name}",
|
||||
"size" : ${instr.length},
|
||||
"encoding": "${instr.encoding}",
|
||||
"mask": "${instr.mask}",
|
||||
"branch": ${instr.modifiesPC},
|
||||
"delay" : ${instr.isConditional?"[1,1]":"1"}
|
||||
}<%}%>
|
||||
]
|
||||
}
|
||||
21
gen_input/templates/CORENAME_instr.yaml.gtl
Normal file
21
gen_input/templates/CORENAME_instr.yaml.gtl
Normal file
@@ -0,0 +1,21 @@
|
||||
<% def getInstructionGroups() {
|
||||
def instrGroups = [:]
|
||||
instructions.each {
|
||||
def groupName = it['instruction'].eContainer().name
|
||||
if(!instrGroups.containsKey(groupName)) {
|
||||
instrGroups[groupName]=[]
|
||||
}
|
||||
instrGroups[groupName]+=it;
|
||||
}
|
||||
instrGroups
|
||||
}%><%int index = 0; getInstructionGroups().each{name, instrList -> %>
|
||||
${name}: <% instrList.each { %>
|
||||
${it.instruction.name}:
|
||||
index: ${index++}
|
||||
encoding: ${it.encoding}
|
||||
mask: ${it.mask}<%if(it.attributes.size) {%>
|
||||
attributes: ${it.attributes}<%}%>
|
||||
size: ${it.length}
|
||||
branch: ${it.modifiesPC}
|
||||
delay: ${it.isConditional?"[1,1]":"1"}<%}}%>
|
||||
|
||||
131
gen_input/templates/CORENAME_sysc.cpp.gtl
Normal file
131
gen_input/templates/CORENAME_sysc.cpp.gtl
Normal file
@@ -0,0 +1,131 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 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 <sysc/iss_factory.h>
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/arch/riscv_hart_mu_p.h>
|
||||
#include <sysc/sc_core_adapter.h>
|
||||
#include <sysc/core_complex.h>
|
||||
#include <array>
|
||||
<%
|
||||
def array_count = coreDef.name.toLowerCase()=="tgc5d" || coreDef.name.toLowerCase()=="tgc5e"? 3 : 2;
|
||||
%>
|
||||
namespace iss {
|
||||
namespace interp {
|
||||
using namespace sysc;
|
||||
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 {
|
||||
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|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()}>>(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|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)
|
||||
namespace tcc {
|
||||
using namespace sysc;
|
||||
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 {
|
||||
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|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()}>>(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|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
|
||||
}
|
||||
// clang-format on
|
||||
390
gen_input/templates/asmjit/CORENAME.cpp.gtl
Normal file
390
gen_input/templates/asmjit/CORENAME.cpp.gtl
Normal file
@@ -0,0 +1,390 @@
|
||||
/*******************************************************************************
|
||||
* 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><%}
|
||||
def aes = functions.find { it.contains('aes') }
|
||||
if(aes != null) {%>
|
||||
#include <vm/aes_sbox.h>
|
||||
<%}%>
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <array>
|
||||
#include <iss/debugger/riscv_target_adapter.h>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
using int128_t = __int128;
|
||||
using uint128_t = unsigned __int128;
|
||||
namespace std {
|
||||
template <> struct make_unsigned<__int128> { typedef unsigned __int128 type; };
|
||||
template <> class __make_unsigned_selector<__int128 unsigned, false, false> {
|
||||
public:
|
||||
typedef unsigned __int128 __type;
|
||||
};
|
||||
template <> struct is_signed<int128_t> { static constexpr bool value = true; };
|
||||
template <> struct is_signed<uint128_t> { static constexpr bool value = false; };
|
||||
template <> struct is_unsigned<int128_t> { static constexpr bool value = false; };
|
||||
template <> struct is_unsigned<uint128_t> { static constexpr bool value = true; };
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
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&, 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);
|
||||
}
|
||||
inline void raise(uint16_t trap_id, uint16_t cause){
|
||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||
this->core.reg.trap_state = trap_val;
|
||||
}
|
||||
|
||||
<%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);
|
||||
/*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);
|
||||
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, jit_holder& jh) {
|
||||
enum {TRAP_ID=1<<16};
|
||||
code_word_t instr = 0;
|
||||
phys_addr_t paddr(pc);
|
||||
auto *const data = (uint8_t *)&instr;
|
||||
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;
|
||||
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;
|
||||
|
||||
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);
|
||||
cc.comment("//Instruction prologue end");
|
||||
|
||||
}
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_instr_epilogue(jit_holder& jh) {
|
||||
auto& cc = jh.cc;
|
||||
|
||||
cc.comment("//Instruction epilogue begin");
|
||||
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));
|
||||
cc.comment("//Instruction epilogue end");
|
||||
|
||||
}
|
||||
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("//block epilogue begin");
|
||||
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));
|
||||
|
||||
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;
|
||||
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
|
||||
1185
gen_input/templates/interp/CORENAME.cpp.gtl
Normal file
1185
gen_input/templates/interp/CORENAME.cpp.gtl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","}
|
||||
{
|
||||
"name" : "${instr.name}",
|
||||
"size" : ${instr.length},
|
||||
"delay" : ${generator.hasAttribute(instr.instruction, com.minres.coredsl.coreDsl.InstrAttribute.COND)?[1,1]:1}
|
||||
}<%}%>
|
||||
]
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2017, 2018 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
<%
|
||||
import com.minres.coredsl.coreDsl.Register
|
||||
import com.minres.coredsl.coreDsl.RegisterFile
|
||||
import com.minres.coredsl.coreDsl.RegisterAlias
|
||||
def getTypeSize(size){
|
||||
if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8
|
||||
}
|
||||
def getOriginalName(reg){
|
||||
if( reg.original instanceof RegisterFile) {
|
||||
if( reg.index != null ) {
|
||||
return reg.original.name+generator.generateHostCode(reg.index)
|
||||
} else {
|
||||
return reg.original.name
|
||||
}
|
||||
} else if(reg.original instanceof Register){
|
||||
return reg.original.name
|
||||
}
|
||||
}
|
||||
def getRegisterNames(){
|
||||
def regNames = []
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{
|
||||
regNames+=reg.name.toLowerCase()+it
|
||||
}
|
||||
} else if(reg instanceof Register){
|
||||
regNames+=reg.name.toLowerCase()
|
||||
}
|
||||
}
|
||||
return regNames
|
||||
}
|
||||
def getRegisterAliasNames(){
|
||||
def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
|
||||
return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
|
||||
} else if(reg instanceof Register){
|
||||
regMap[reg.name]?:reg.name.toLowerCase()
|
||||
}
|
||||
}.flatten()
|
||||
}
|
||||
%>
|
||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||
#define _${coreDef.name.toUpperCase()}_H_
|
||||
|
||||
#include <array>
|
||||
#include <iss/arch/traits.h>
|
||||
#include <iss/arch_if.h>
|
||||
#include <iss/vm_if.h>
|
||||
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
struct ${coreDef.name.toLowerCase()};
|
||||
|
||||
template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||
|
||||
constexpr static char const* const core_type = "${coreDef.name}";
|
||||
|
||||
static constexpr std::array<const char*, ${getRegisterNames().size}> reg_names{
|
||||
{"${getRegisterNames().join("\", \"")}"}};
|
||||
|
||||
static constexpr std::array<const char*, ${getRegisterAliasNames().size}> reg_aliases{
|
||||
{"${getRegisterAliasNames().join("\", \"")}"}};
|
||||
|
||||
enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}};
|
||||
|
||||
constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0};
|
||||
|
||||
enum reg_e {<%
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{%>
|
||||
${reg.name}${it},<%
|
||||
}
|
||||
} else if(reg instanceof Register){ %>
|
||||
${reg.name},<%
|
||||
}
|
||||
}%>
|
||||
NUM_REGS,
|
||||
NEXT_${pc.name}=NUM_REGS,
|
||||
TRAP_STATE,
|
||||
PENDING_TRAP,
|
||||
MACHINE_STATE,
|
||||
LAST_BRANCH,
|
||||
ICOUNT<%
|
||||
allRegs.each { reg ->
|
||||
if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>,
|
||||
${reg.name} = ${aliasname}<%
|
||||
}
|
||||
}%>
|
||||
};
|
||||
|
||||
using reg_t = uint${regDataWidth}_t;
|
||||
|
||||
using addr_t = uint${addrDataWidth}_t;
|
||||
|
||||
using code_word_t = uint${addrDataWidth}_t; //TODO: check removal
|
||||
|
||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
static constexpr std::array<const uint32_t, ${regSizes.size}> reg_bit_widths{
|
||||
{${regSizes.join(",")}}};
|
||||
|
||||
static constexpr std::array<const uint32_t, ${regOffsets.size}> reg_byte_offsets{
|
||||
{${regOffsets.join(",")}}};
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
enum sreg_flag_e { FLAGS };
|
||||
|
||||
enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} };
|
||||
};
|
||||
|
||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||
|
||||
using virt_addr_t = typename traits<${coreDef.name.toLowerCase()}>::virt_addr_t;
|
||||
using phys_addr_t = typename traits<${coreDef.name.toLowerCase()}>::phys_addr_t;
|
||||
using reg_t = typename traits<${coreDef.name.toLowerCase()}>::reg_t;
|
||||
using addr_t = typename traits<${coreDef.name.toLowerCase()}>::addr_t;
|
||||
|
||||
${coreDef.name.toLowerCase()}();
|
||||
~${coreDef.name.toLowerCase()}();
|
||||
|
||||
void reset(uint64_t address=0) override;
|
||||
|
||||
uint8_t* get_regs_base_ptr() override;
|
||||
/// deprecated
|
||||
void get_reg(short idx, std::vector<uint8_t>& value) override {}
|
||||
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
|
||||
/// deprecated
|
||||
bool get_flag(int flag) override {return false;}
|
||||
void set_flag(int, bool value) override {};
|
||||
/// deprecated
|
||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||
|
||||
inline uint64_t get_icount() { return reg.icount; }
|
||||
|
||||
inline bool should_stop() { return interrupt_sim; }
|
||||
|
||||
inline uint64_t stop_code() { return interrupt_sim; }
|
||||
|
||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||
if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
||||
} else
|
||||
return virt2phys(addr);
|
||||
}
|
||||
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
||||
|
||||
protected:
|
||||
struct ${coreDef.name}_regs {<%
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{%>
|
||||
uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<%
|
||||
}
|
||||
} else if(reg instanceof Register){ %>
|
||||
uint${generator.getSize(reg)}_t ${reg.name} = 0;<%
|
||||
}
|
||||
}%>
|
||||
uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0;
|
||||
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
|
||||
uint64_t icount = 0;
|
||||
} reg;
|
||||
|
||||
std::array<address_type, 4> addr_mode;
|
||||
|
||||
uint64_t interrupt_sim=0;
|
||||
<%
|
||||
def fcsr = allRegs.find {it.name=='FCSR'}
|
||||
if(fcsr != null) {%>
|
||||
uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;}
|
||||
void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;}
|
||||
<%} else { %>
|
||||
uint32_t get_fcsr(){return 0;}
|
||||
void set_fcsr(uint32_t val){}
|
||||
<%}%>
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
||||
@@ -1,107 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2017, 2018 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
<%
|
||||
import com.minres.coredsl.coreDsl.Register
|
||||
import com.minres.coredsl.coreDsl.RegisterFile
|
||||
import com.minres.coredsl.coreDsl.RegisterAlias
|
||||
def getOriginalName(reg){
|
||||
if( reg.original instanceof RegisterFile) {
|
||||
if( reg.index != null ) {
|
||||
return reg.original.name+generator.generateHostCode(reg.index)
|
||||
} else {
|
||||
return reg.original.name
|
||||
}
|
||||
} else if(reg.original instanceof Register){
|
||||
return reg.original.name
|
||||
}
|
||||
}
|
||||
def getRegisterNames(){
|
||||
def regNames = []
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{
|
||||
regNames+=reg.name.toLowerCase()+it
|
||||
}
|
||||
} else if(reg instanceof Register){
|
||||
regNames+=reg.name.toLowerCase()
|
||||
}
|
||||
}
|
||||
return regNames
|
||||
}
|
||||
def getRegisterAliasNames(){
|
||||
def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
|
||||
return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
|
||||
} else if(reg instanceof Register){
|
||||
regMap[reg.name]?:reg.name.toLowerCase()
|
||||
}
|
||||
}.flatten()
|
||||
}
|
||||
%>
|
||||
#include "util/ities.h"
|
||||
#include <util/logging.h>
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
|
||||
using namespace iss::arch;
|
||||
|
||||
constexpr std::array<const char*, ${getRegisterNames().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_names;
|
||||
constexpr std::array<const char*, ${getRegisterAliasNames().size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_aliases;
|
||||
constexpr std::array<const uint32_t, ${regSizes.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_bit_widths;
|
||||
constexpr std::array<const uint32_t, ${regOffsets.size}> iss::arch::traits<iss::arch::${coreDef.name.toLowerCase()}>::reg_byte_offsets;
|
||||
|
||||
${coreDef.name.toLowerCase()}::${coreDef.name.toLowerCase()}() {
|
||||
reg.icount = 0;
|
||||
}
|
||||
|
||||
${coreDef.name.toLowerCase()}::~${coreDef.name.toLowerCase()}() = default;
|
||||
|
||||
void ${coreDef.name.toLowerCase()}::reset(uint64_t address) {
|
||||
for(size_t i=0; i<traits<${coreDef.name.toLowerCase()}>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<${coreDef.name.toLowerCase()}>::reg_t),0));
|
||||
reg.PC=address;
|
||||
reg.NEXT_PC=reg.PC;
|
||||
reg.trap_state=0;
|
||||
reg.machine_state=0x3;
|
||||
reg.icount=0;
|
||||
}
|
||||
|
||||
uint8_t *${coreDef.name.toLowerCase()}::get_regs_base_ptr() {
|
||||
return reinterpret_cast<uint8_t*>(®);
|
||||
}
|
||||
|
||||
${coreDef.name.toLowerCase()}::phys_addr_t ${coreDef.name.toLowerCase()}::virt2phys(const iss::addr_t &pc) {
|
||||
return phys_addr_t(pc); // change logical address to physical address
|
||||
}
|
||||
|
||||
@@ -1,247 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2020 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include "../fp_functions.h"
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/iss.h>
|
||||
#include <iss/interp/vm_base.h>
|
||||
#include <util/logging.h>
|
||||
#include <sstream>
|
||||
|
||||
#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 interp {
|
||||
namespace ${coreDef.name.toLowerCase()} {
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
template <typename ARCH> class vm_impl : public iss::interp::vm_base<ARCH> {
|
||||
public:
|
||||
using super = typename iss::interp::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 addr_t = typename super::addr_t;
|
||||
using reg_t = typename traits<ARCH>::reg_t;
|
||||
using iss::interp::vm_base<ARCH>::get_reg;
|
||||
|
||||
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 (super::tgt_adapter == nullptr)
|
||||
super::tgt_adapter = new riscv_target_adapter<ARCH>(srv, this->get_arch());
|
||||
return super::tgt_adapter;
|
||||
}
|
||||
|
||||
protected:
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_ret_t = virt_addr_t;
|
||||
using compile_func = compile_ret_t (this_class::*)(virt_addr_t &pc, code_word_t instr);
|
||||
|
||||
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
||||
|
||||
virt_addr_t execute_inst(virt_addr_t start, std::function<bool(void)> pred) override;
|
||||
|
||||
// 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(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void raise_trap(uint16_t trap_id, uint16_t cause){
|
||||
auto trap_val = 0x80ULL << 24 | (cause << 16) | trap_id;
|
||||
this->template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE) = trap_val;
|
||||
this->template get_reg<uint32_t>(arch::traits<ARCH>::NEXT_PC) = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
void leave_trap(unsigned lvl){
|
||||
this->core.leave_trap(lvl);
|
||||
auto pc_val = super::template read_mem<reg_t>(traits<ARCH>::CSR, (lvl << 8) + 0x41);
|
||||
this->template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC) = pc_val;
|
||||
this->template get_reg<uint32_t>(arch::traits<ARCH>::LAST_BRANCH) = std::numeric_limits<uint32_t>::max();
|
||||
}
|
||||
|
||||
void wait(unsigned type){
|
||||
this->core.wait_until(type);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/****************************************************************************
|
||||
* start opcode definitions
|
||||
****************************************************************************/
|
||||
struct InstructionDesriptor {
|
||||
size_t length;
|
||||
uint32_t value;
|
||||
uint32_t mask;
|
||||
compile_func op;
|
||||
};
|
||||
|
||||
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||
/* instruction ${instr.instruction.name} */
|
||||
{${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||
}};
|
||||
|
||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||
/* instruction ${idx}: ${instr.name} */
|
||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr){<%instr.code.eachLine{%>
|
||||
${it}<%}%>
|
||||
}
|
||||
<%}%>
|
||||
/****************************************************************************
|
||||
* end opcode definitions
|
||||
****************************************************************************/
|
||||
compile_ret_t illegal_intruction(virt_addr_t &pc, code_word_t instr) {
|
||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||
return pc;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
||||
volatile CODE_WORD x = insn;
|
||||
insn = 2 * x;
|
||||
}
|
||||
|
||||
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) {
|
||||
qlut[0] = lut_00.data();
|
||||
qlut[1] = lut_01.data();
|
||||
qlut[2] = lut_10.data();
|
||||
qlut[3] = lut_11.data();
|
||||
for (auto instr : instr_descr) {
|
||||
auto quantrant = instr.value & 0x3;
|
||||
expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(void)> pred) {
|
||||
// we fetch at max 4 byte, alignment is 2
|
||||
enum {TRAP_ID=1<<16};
|
||||
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||
code_word_t insn = 0;
|
||||
auto *const data = (uint8_t *)&insn;
|
||||
auto pc=start;
|
||||
while(pred){
|
||||
auto paddr = this->core.v2p(pc);
|
||||
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
|
||||
if (this->core.read(paddr, 2, data) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
||||
if ((insn & 0x3) == 0x3) // this is a 32bit instruction
|
||||
if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
||||
} else {
|
||||
if (this->core.read(paddr, 4, data) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
||||
}
|
||||
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
auto lut_val = extract_fields(insn);
|
||||
auto f = qlut[insn & 0x3][lut_val];
|
||||
if (!f)
|
||||
f = &this_class::illegal_intruction;
|
||||
pc = (this->*f)(pc, insn);
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
|
||||
} // namespace mnrv32
|
||||
|
||||
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 interp
|
||||
} // namespace iss
|
||||
411
gen_input/templates/llvm/CORENAME.cpp.gtl
Normal file
411
gen_input/templates/llvm/CORENAME.cpp.gtl
Normal file
@@ -0,0 +1,411 @@
|
||||
/*******************************************************************************
|
||||
* 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>
|
||||
// vm_base needs to be included before gdb_session as termios.h (via boost and gdb_server) has a define which clashes with a variable
|
||||
// name in ConstantRange.h
|
||||
#include <iss/llvm/vm_base.h>
|
||||
#include <iss/iss.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/instruction_decoder.h>
|
||||
#include <util/logging.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 llvm {
|
||||
namespace fp_impl {
|
||||
void add_fp_functions_2_module(::llvm::Module *, unsigned, unsigned);
|
||||
}
|
||||
|
||||
namespace ${coreDef.name.toLowerCase()} {
|
||||
using namespace ::llvm;
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> {
|
||||
public:
|
||||
using traits = arch::traits<ARCH>;
|
||||
using super = typename iss::llvm::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 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 vm_base<ARCH>::get_reg_ptr;
|
||||
|
||||
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) {
|
||||
return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
|
||||
}
|
||||
|
||||
void setup_module(Module* m) override {
|
||||
super::setup_module(m);
|
||||
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) {
|
||||
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||
}
|
||||
|
||||
std::tuple<continuation_e, BasicBlock *> gen_single_inst_behavior(virt_addr_t &, BasicBlock *) override;
|
||||
|
||||
void gen_leave_behavior(BasicBlock *leave_blk) override;
|
||||
void gen_raise_trap(uint16_t trap_id, uint16_t cause);
|
||||
void gen_leave_trap(unsigned lvl);
|
||||
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_instr_prologue();
|
||||
void gen_instr_epilogue(BasicBlock *bb);
|
||||
|
||||
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||
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) {
|
||||
Value *next_pc_v = this->builder.CreateSExtOrTrunc(this->gen_const(traits::XLEN, pc.val),
|
||||
this->get_type(traits::XLEN));
|
||||
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||
}
|
||||
|
||||
// some compile time constants
|
||||
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
|
||||
code_word_t instr,
|
||||
BasicBlock *bb);
|
||||
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}<%}
|
||||
}
|
||||
if(fcsr != null) {%>
|
||||
Value* NaNBox16(BasicBlock* bb, Value* NaNBox16_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 16)
|
||||
return this->gen_ext(NaNBox16_val, traits::FLEN, false);
|
||||
auto box = this->builder.CreateNot((this->gen_ext(0, 32, false)));
|
||||
return this->gen_ext((this->builder.CreateOr(this->builder.CreateShl(this->gen_ext(box, traits::FLEN), 16), this->gen_ext(NaNBox16_val, traits::FLEN))), traits::FLEN, false);
|
||||
}
|
||||
Value* NaNBox32(BasicBlock* bb, Value* NaNBox32_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 32)
|
||||
return this->gen_ext(NaNBox32_val, traits::FLEN, false);
|
||||
auto box = this->builder.CreateNot((this->gen_ext(0, 64, false)));
|
||||
return this->gen_ext((this->builder.CreateOr(this->builder.CreateShl(this->gen_ext(box, traits::FLEN), 32), this->gen_ext(NaNBox32_val, traits::FLEN))), traits::FLEN, false);
|
||||
}
|
||||
Value* NaNBox64(BasicBlock* bb, Value* NaNBox64_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 64)
|
||||
return this->gen_ext(NaNBox64_val, traits::FLEN, false);
|
||||
auto box = this->builder.CreateNot((this->gen_ext(0, 128, false)));
|
||||
return this->gen_ext((this->builder.CreateOr(this->builder.CreateShl(this->gen_ext(box, traits::FLEN), 64), this->gen_ext(NaNBox64_val, traits::FLEN))), traits::FLEN, false);
|
||||
}
|
||||
|
||||
<%}%>
|
||||
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} */
|
||||
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}<%}%>
|
||||
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
|
||||
****************************************************************************/
|
||||
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->builder.CreateStore(this->builder.CreateLoad(this->get_typeptr(traits::NEXT_PC), get_reg_ptr(traits::NEXT_PC), true),
|
||||
get_reg_ptr(traits::PC), true);
|
||||
this->builder.CreateStore(
|
||||
this->builder.CreateAdd(this->builder.CreateLoad(this->get_typeptr(traits::ICOUNT), get_reg_ptr(traits::ICOUNT), true),
|
||||
this->gen_const(64U, 1)),
|
||||
get_reg_ptr(traits::ICOUNT), true);
|
||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||
this->set_tval(instr);
|
||||
this->gen_raise_trap(0, 2); // illegal instruction trap
|
||||
this->gen_sync(iss::POST_SYNC, instr_descr.size());
|
||||
bb = this->leave_blk;
|
||||
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 instr) {
|
||||
volatile CODE_WORD x = instr;
|
||||
instr = 2 * x;
|
||||
}
|
||||
|
||||
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>
|
||||
std::tuple<continuation_e, BasicBlock *>
|
||||
vm_impl<ARCH>::gen_single_inst_behavior(virt_addr_t &pc, BasicBlock *this_block) {
|
||||
// we fetch at max 4 byte, alignment is 2
|
||||
enum {TRAP_ID=1<<16};
|
||||
code_word_t instr = 0;
|
||||
// const typename traits::addr_t upper_bits = ~traits::PGMASK;
|
||||
phys_addr_t paddr(pc);
|
||||
auto *const data = (uint8_t *)&instr;
|
||||
auto res = this->core.read(paddr, 4, data);
|
||||
if (res != iss::Ok)
|
||||
return std::make_tuple(ILLEGAL_FETCH, nullptr);
|
||||
if (instr == 0x0000006f || (instr&0xffff)==0xa001){
|
||||
this->builder.CreateBr(this->leave_blk);
|
||||
return std::make_tuple(JUMP_TO_SELF, nullptr);
|
||||
}
|
||||
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, this_block);
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
|
||||
this->builder.SetInsertPoint(leave_blk);
|
||||
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) {
|
||||
auto *TRAP_val = this->gen_const(32, 0x80 << 24 | (cause << 16) | trap_id);
|
||||
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits::TRAP_STATE), true);
|
||||
this->builder.CreateBr(this->trap_blk);
|
||||
}
|
||||
|
||||
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)) };
|
||||
this->builder.CreateCall(this->mod->getFunction("leave_trap"), args);
|
||||
this->builder.CreateStore(this->gen_const(32U, static_cast<int>(UNKNOWN_JUMP)), get_reg_ptr(traits::LAST_BRANCH), false);
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
void vm_impl<ARCH>::gen_wait(unsigned type) {
|
||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) };
|
||||
this->builder.CreateCall(this->mod->getFunction("wait"), args);
|
||||
}
|
||||
|
||||
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);
|
||||
auto *trap_state_val = this->builder.CreateLoad(this->get_typeptr(traits::TRAP_STATE), get_reg_ptr(traits::TRAP_STATE), true);
|
||||
auto *cur_pc_val = this->builder.CreateLoad(this->get_typeptr(traits::PC), get_reg_ptr(traits::PC), true);
|
||||
std::vector<Value *> args{this->core_ptr,
|
||||
this->adj_to64(trap_state_val),
|
||||
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.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);
|
||||
}
|
||||
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>
|
||||
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(
|
||||
ICmpInst::ICMP_EQ, v,
|
||||
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
|
||||
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);
|
||||
//increment cyclecount
|
||||
auto* cycle_val = this->builder.CreateAdd(
|
||||
this->builder.CreateLoad(this->get_typeptr(arch::traits<ARCH>::CYCLE), get_reg_ptr(arch::traits<ARCH>::CYCLE)), this->gen_const(64U, 1));
|
||||
this->builder.CreateStore(cycle_val, get_reg_ptr(arch::traits<ARCH>::CYCLE), false);
|
||||
}
|
||||
|
||||
} // namespace ${coreDef.name.toLowerCase()}
|
||||
|
||||
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 llvm
|
||||
} // 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|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 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(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}};
|
||||
}),
|
||||
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 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(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}};
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"${coreDef.name}" : [<%instructions.eachWithIndex{instr,index -> %>${index==0?"":","}
|
||||
{
|
||||
"name" : "${instr.name}",
|
||||
"size" : ${instr.length},
|
||||
"delay" : ${generator.hasAttribute(instr.instruction, com.minres.coredsl.coreDsl.InstrAttribute.COND)?[1,1]:1}
|
||||
}<%}%>
|
||||
]
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2017, 2018 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
<%
|
||||
import com.minres.coredsl.coreDsl.Register
|
||||
import com.minres.coredsl.coreDsl.RegisterFile
|
||||
import com.minres.coredsl.coreDsl.RegisterAlias
|
||||
def getTypeSize(size){
|
||||
if(size > 32) 64 else if(size > 16) 32 else if(size > 8) 16 else 8
|
||||
}
|
||||
def getOriginalName(reg){
|
||||
if( reg.original instanceof RegisterFile) {
|
||||
if( reg.index != null ) {
|
||||
return reg.original.name+generator.generateHostCode(reg.index)
|
||||
} else {
|
||||
return reg.original.name
|
||||
}
|
||||
} else if(reg.original instanceof Register){
|
||||
return reg.original.name
|
||||
}
|
||||
}
|
||||
def getRegisterNames(){
|
||||
def regNames = []
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{
|
||||
regNames+=reg.name.toLowerCase()+it
|
||||
}
|
||||
} else if(reg instanceof Register){
|
||||
regNames+=reg.name.toLowerCase()
|
||||
}
|
||||
}
|
||||
return regNames
|
||||
}
|
||||
def getRegisterAliasNames(){
|
||||
def regMap = allRegs.findAll{it instanceof RegisterAlias }.collectEntries {[getOriginalName(it), it.name]}
|
||||
return allRegs.findAll{it instanceof Register || it instanceof RegisterFile}.collect{reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
return (reg.range.right..reg.range.left).collect{ (regMap[reg.name]?:regMap[reg.name+it]?:reg.name.toLowerCase()+it).toLowerCase() }
|
||||
} else if(reg instanceof Register){
|
||||
regMap[reg.name]?:reg.name.toLowerCase()
|
||||
}
|
||||
}.flatten()
|
||||
}
|
||||
%>
|
||||
#ifndef _${coreDef.name.toUpperCase()}_H_
|
||||
#define _${coreDef.name.toUpperCase()}_H_
|
||||
|
||||
#include <array>
|
||||
#include <iss/arch/traits.h>
|
||||
#include <iss/arch_if.h>
|
||||
#include <iss/vm_if.h>
|
||||
|
||||
namespace iss {
|
||||
namespace arch {
|
||||
|
||||
struct ${coreDef.name.toLowerCase()};
|
||||
|
||||
template <> struct traits<${coreDef.name.toLowerCase()}> {
|
||||
|
||||
constexpr static char const* const core_type = "${coreDef.name}";
|
||||
|
||||
static constexpr std::array<const char*, ${getRegisterNames().size}> reg_names{
|
||||
{"${getRegisterNames().join("\", \"")}"}};
|
||||
|
||||
static constexpr std::array<const char*, ${getRegisterAliasNames().size}> reg_aliases{
|
||||
{"${getRegisterAliasNames().join("\", \"")}"}};
|
||||
|
||||
enum constants {${coreDef.constants.collect{c -> c.name+"="+c.value}.join(', ')}};
|
||||
|
||||
constexpr static unsigned FP_REGS_SIZE = ${coreDef.constants.find {it.name=='FLEN'}?.value?:0};
|
||||
|
||||
enum reg_e {<%
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{%>
|
||||
${reg.name}${it},<%
|
||||
}
|
||||
} else if(reg instanceof Register){ %>
|
||||
${reg.name},<%
|
||||
}
|
||||
}%>
|
||||
NUM_REGS,
|
||||
NEXT_${pc.name}=NUM_REGS,
|
||||
TRAP_STATE,
|
||||
PENDING_TRAP,
|
||||
MACHINE_STATE,
|
||||
LAST_BRANCH,
|
||||
ICOUNT<%
|
||||
allRegs.each { reg ->
|
||||
if(reg instanceof RegisterAlias){ def aliasname=getOriginalName(reg)%>,
|
||||
${reg.name} = ${aliasname}<%
|
||||
}
|
||||
}%>
|
||||
};
|
||||
|
||||
using reg_t = uint${regDataWidth}_t;
|
||||
|
||||
using addr_t = uint${addrDataWidth}_t;
|
||||
|
||||
using code_word_t = uint${addrDataWidth}_t; //TODO: check removal
|
||||
|
||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
static constexpr std::array<const uint32_t, ${regSizes.size}> reg_bit_widths{
|
||||
{${regSizes.join(",")}}};
|
||||
|
||||
static constexpr std::array<const uint32_t, ${regOffsets.size}> reg_byte_offsets{
|
||||
{${regOffsets.join(",")}}};
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
enum sreg_flag_e { FLAGS };
|
||||
|
||||
enum mem_type_e { ${allSpaces.collect{s -> s.name}.join(', ')} };
|
||||
};
|
||||
|
||||
struct ${coreDef.name.toLowerCase()}: public arch_if {
|
||||
|
||||
using virt_addr_t = typename traits<${coreDef.name.toLowerCase()}>::virt_addr_t;
|
||||
using phys_addr_t = typename traits<${coreDef.name.toLowerCase()}>::phys_addr_t;
|
||||
using reg_t = typename traits<${coreDef.name.toLowerCase()}>::reg_t;
|
||||
using addr_t = typename traits<${coreDef.name.toLowerCase()}>::addr_t;
|
||||
|
||||
${coreDef.name.toLowerCase()}();
|
||||
~${coreDef.name.toLowerCase()}();
|
||||
|
||||
void reset(uint64_t address=0) override;
|
||||
|
||||
uint8_t* get_regs_base_ptr() override;
|
||||
/// deprecated
|
||||
void get_reg(short idx, std::vector<uint8_t>& value) override {}
|
||||
void set_reg(short idx, const std::vector<uint8_t>& value) override {}
|
||||
/// deprecated
|
||||
bool get_flag(int flag) override {return false;}
|
||||
void set_flag(int, bool value) override {};
|
||||
/// deprecated
|
||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||
|
||||
inline uint64_t get_icount() { return reg.icount; }
|
||||
|
||||
inline bool should_stop() { return interrupt_sim; }
|
||||
|
||||
inline uint64_t stop_code() { return interrupt_sim; }
|
||||
|
||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||
if (addr.space != traits<${coreDef.name.toLowerCase()}>::MEM || addr.type == iss::address_type::PHYSICAL ||
|
||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL) {
|
||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<${coreDef.name.toLowerCase()}>::addr_mask);
|
||||
} else
|
||||
return virt2phys(addr);
|
||||
}
|
||||
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
inline uint32_t get_last_branch() { return reg.last_branch; }
|
||||
|
||||
protected:
|
||||
struct ${coreDef.name}_regs {<%
|
||||
allRegs.each { reg ->
|
||||
if( reg instanceof RegisterFile) {
|
||||
(reg.range.right..reg.range.left).each{%>
|
||||
uint${generator.getSize(reg)}_t ${reg.name}${it} = 0;<%
|
||||
}
|
||||
} else if(reg instanceof Register){ %>
|
||||
uint${generator.getSize(reg)}_t ${reg.name} = 0;<%
|
||||
}
|
||||
}%>
|
||||
uint${generator.getSize(pc)}_t NEXT_${pc.name} = 0;
|
||||
uint32_t trap_state = 0, pending_trap = 0, machine_state = 0, last_branch = 0;
|
||||
uint64_t icount = 0;
|
||||
} reg;
|
||||
|
||||
std::array<address_type, 4> addr_mode;
|
||||
|
||||
uint64_t interrupt_sim=0;
|
||||
<%
|
||||
def fcsr = allRegs.find {it.name=='FCSR'}
|
||||
if(fcsr != null) {%>
|
||||
uint${generator.getSize(fcsr)}_t get_fcsr(){return reg.FCSR;}
|
||||
void set_fcsr(uint${generator.getSize(fcsr)}_t val){reg.FCSR = val;}
|
||||
<%} else { %>
|
||||
uint32_t get_fcsr(){return 0;}
|
||||
void set_fcsr(uint32_t val){}
|
||||
<%}%>
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif /* _${coreDef.name.toUpperCase()}_H_ */
|
||||
@@ -1,325 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2017, 2018 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.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include <iss/arch/${coreDef.name.toLowerCase()}.h>
|
||||
#include <iss/arch/riscv_hart_m_p.h>
|
||||
#include <iss/debugger/gdb_session.h>
|
||||
#include <iss/debugger/server.h>
|
||||
#include <iss/iss.h>
|
||||
#include <iss/llvm/vm_base.h>
|
||||
#include <util/logging.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 llvm {
|
||||
namespace fp_impl {
|
||||
void add_fp_functions_2_module(::llvm::Module *, unsigned, unsigned);
|
||||
}
|
||||
|
||||
namespace ${coreDef.name.toLowerCase()} {
|
||||
using namespace ::llvm;
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
template <typename ARCH> class vm_impl : public iss::llvm::vm_base<ARCH> {
|
||||
public:
|
||||
using super = typename iss::llvm::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 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 vm_base<ARCH>::get_reg_ptr;
|
||||
|
||||
inline const char *name(size_t index){return traits<ARCH>::reg_aliases.at(index);}
|
||||
|
||||
template <typename T> inline ConstantInt *size(T type) {
|
||||
return ConstantInt::get(getContext(), APInt(32, type->getType()->getScalarSizeInBits()));
|
||||
}
|
||||
|
||||
void setup_module(Module* m) override {
|
||||
super::setup_module(m);
|
||||
iss::llvm::fp_impl::add_fp_functions_2_module(m, traits<ARCH>::FP_REGS_SIZE, traits<ARCH>::XLEN);
|
||||
}
|
||||
|
||||
inline Value *gen_choose(Value *cond, Value *trueVal, Value *falseVal, unsigned size) {
|
||||
return super::gen_cond_assign(cond, this->gen_ext(trueVal, size), this->gen_ext(falseVal, size));
|
||||
}
|
||||
|
||||
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_raise_trap(uint16_t trap_id, uint16_t cause);
|
||||
|
||||
void gen_leave_trap(unsigned lvl);
|
||||
|
||||
void gen_wait(unsigned type);
|
||||
|
||||
void gen_trap_behavior(BasicBlock *) override;
|
||||
|
||||
void gen_trap_check(BasicBlock *bb);
|
||||
|
||||
inline Value *gen_reg_load(unsigned i, unsigned level = 0) {
|
||||
return this->builder.CreateLoad(get_reg_ptr(i), false);
|
||||
}
|
||||
|
||||
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),
|
||||
this->get_type(traits<ARCH>::XLEN));
|
||||
this->builder.CreateStore(next_pc_v, get_reg_ptr(reg_num), true);
|
||||
}
|
||||
|
||||
// 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(EXTR_MASK32), LUT_SIZE_C = 1 << util::bit_count(EXTR_MASK16) };
|
||||
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_func = std::tuple<continuation_e, BasicBlock *> (this_class::*)(virt_addr_t &pc,
|
||||
code_word_t instr,
|
||||
BasicBlock *bb);
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
/****************************************************************************
|
||||
* start opcode definitions
|
||||
****************************************************************************/
|
||||
struct InstructionDesriptor {
|
||||
size_t length;
|
||||
uint32_t value;
|
||||
uint32_t mask;
|
||||
compile_func op;
|
||||
};
|
||||
|
||||
const std::array<InstructionDesriptor, ${instructions.size}> instr_descr = {{
|
||||
/* entries are: size, valid value, valid mask, function ptr */<%instructions.each{instr -> %>
|
||||
/* instruction ${instr.instruction.name} */
|
||||
{${instr.length}, ${instr.value}, ${instr.mask}, &this_class::__${generator.functionName(instr.name)}},<%}%>
|
||||
}};
|
||||
|
||||
/* instruction definitions */<%instructions.eachWithIndex{instr, idx -> %>
|
||||
/* 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{%>
|
||||
${it}<%}%>
|
||||
}
|
||||
<%}%>
|
||||
/****************************************************************************
|
||||
* end opcode definitions
|
||||
****************************************************************************/
|
||||
std::tuple<continuation_e, BasicBlock *> illegal_intruction(virt_addr_t &pc, code_word_t instr, BasicBlock *bb) {
|
||||
this->gen_sync(iss::PRE_SYNC, instr_descr.size());
|
||||
this->builder.CreateStore(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), true),
|
||||
get_reg_ptr(traits<ARCH>::PC), true);
|
||||
this->builder.CreateStore(
|
||||
this->builder.CreateAdd(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::ICOUNT), true),
|
||||
this->gen_const(64U, 1)),
|
||||
get_reg_ptr(traits<ARCH>::ICOUNT), true);
|
||||
pc = pc + ((instr & 3) == 3 ? 4 : 2);
|
||||
this->gen_raise_trap(0, 2); // illegal instruction trap
|
||||
this->gen_sync(iss::POST_SYNC, instr_descr.size());
|
||||
this->gen_trap_check(this->leave_blk);
|
||||
return std::make_tuple(BRANCH, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
|
||||
volatile CODE_WORD x = insn;
|
||||
insn = 2 * x;
|
||||
}
|
||||
|
||||
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) {
|
||||
qlut[0] = lut_00.data();
|
||||
qlut[1] = lut_01.data();
|
||||
qlut[2] = lut_10.data();
|
||||
qlut[3] = lut_11.data();
|
||||
for (auto instr : instr_descr) {
|
||||
auto quantrant = instr.value & 0x3;
|
||||
expand_bit_mask(29, lutmasks[quantrant], instr.value >> 2, instr.mask >> 2, 0, qlut[quantrant], instr.op);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ARCH>
|
||||
std::tuple<continuation_e, BasicBlock *>
|
||||
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
|
||||
enum {TRAP_ID=1<<16};
|
||||
code_word_t insn = 0;
|
||||
const typename traits<ARCH>::addr_t upper_bits = ~traits<ARCH>::PGMASK;
|
||||
phys_addr_t paddr(pc);
|
||||
auto *const data = (uint8_t *)&insn;
|
||||
paddr = this->core.v2p(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);
|
||||
if (res != iss::Ok) throw trap_access(TRAP_ID, pc.val);
|
||||
}
|
||||
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
||||
// curr pc on stack
|
||||
++inst_cnt;
|
||||
auto lut_val = extract_fields(insn);
|
||||
auto f = qlut[insn & 0x3][lut_val];
|
||||
if (f == nullptr) {
|
||||
f = &this_class::illegal_intruction;
|
||||
}
|
||||
return (this->*f)(pc, insn, this_block);
|
||||
}
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_behavior(BasicBlock *leave_blk) {
|
||||
this->builder.SetInsertPoint(leave_blk);
|
||||
this->builder.CreateRet(this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::NEXT_PC), false));
|
||||
}
|
||||
|
||||
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);
|
||||
this->builder.CreateStore(TRAP_val, get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||
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_leave_trap(unsigned lvl) {
|
||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, lvl)) };
|
||||
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(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) {
|
||||
std::vector<Value *> args{ this->core_ptr, ConstantInt::get(getContext(), APInt(64, type)) };
|
||||
this->builder.CreateCall(this->mod->getFunction("wait"), args);
|
||||
}
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_trap_behavior(BasicBlock *trap_blk) {
|
||||
this->builder.SetInsertPoint(trap_blk);
|
||||
auto *trap_state_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::TRAP_STATE), true);
|
||||
this->builder.CreateStore(this->gen_const(32U, std::numeric_limits<uint32_t>::max()),
|
||||
get_reg_ptr(traits<ARCH>::LAST_BRANCH), false);
|
||||
std::vector<Value *> args{this->core_ptr, this->adj_to64(trap_state_val),
|
||||
this->adj_to64(this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::PC), false))};
|
||||
this->builder.CreateCall(this->mod->getFunction("enter_trap"), args);
|
||||
auto *trap_addr_val = this->builder.CreateLoad(get_reg_ptr(traits<ARCH>::NEXT_PC), false);
|
||||
this->builder.CreateRet(trap_addr_val);
|
||||
}
|
||||
|
||||
template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(BasicBlock *bb) {
|
||||
auto *v = this->builder.CreateLoad(get_reg_ptr(arch::traits<ARCH>::TRAP_STATE), true);
|
||||
this->gen_cond_branch(this->builder.CreateICmp(
|
||||
ICmpInst::ICMP_EQ, v,
|
||||
ConstantInt::get(getContext(), APInt(v->getType()->getIntegerBitWidth(), 0))),
|
||||
bb, this->trap_blk, 1);
|
||||
}
|
||||
|
||||
} // namespace ${coreDef.name.toLowerCase()}
|
||||
|
||||
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 llvm
|
||||
} // namespace iss
|
||||
420
gen_input/templates/tcc/CORENAME.cpp.gtl
Normal file
420
gen_input/templates/tcc/CORENAME.cpp.gtl
Normal file
@@ -0,0 +1,420 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (C) 2020-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/tcc/vm_base.h>
|
||||
#include <util/logging.h>
|
||||
#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
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <array>
|
||||
#include <iss/debugger/riscv_target_adapter.h>
|
||||
|
||||
namespace iss {
|
||||
namespace tcc {
|
||||
namespace ${coreDef.name.toLowerCase()} {
|
||||
using namespace iss::arch;
|
||||
using namespace iss::debugger;
|
||||
|
||||
template <typename ARCH> class vm_impl : public iss::tcc::vm_base<ARCH> {
|
||||
public:
|
||||
using traits = arch::traits<ARCH>;
|
||||
using super = typename iss::tcc::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 traits::mem_type_e;
|
||||
using addr_t = typename super::addr_t;
|
||||
using tu_builder = typename super::tu_builder;
|
||||
|
||||
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 vm_base<ARCH>::get_reg_ptr;
|
||||
|
||||
using this_class = vm_impl<ARCH>;
|
||||
using compile_ret_t = continuation_e;
|
||||
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);}
|
||||
<%
|
||||
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 {
|
||||
super::setup_module(m);
|
||||
}
|
||||
|
||||
compile_ret_t gen_single_inst_behavior(virt_addr_t &, tu_builder&) override;
|
||||
|
||||
void gen_trap_behavior(tu_builder& tu) override;
|
||||
|
||||
void gen_raise_trap(tu_builder& tu, uint16_t trap_id, uint16_t cause);
|
||||
|
||||
void gen_leave_trap(tu_builder& tu, unsigned lvl);
|
||||
|
||||
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) {
|
||||
tu("if(*trap_state!=0) goto trap_entry;");
|
||||
}
|
||||
|
||||
inline void gen_set_pc(tu_builder& tu, virt_addr_t pc, unsigned reg_num) {
|
||||
switch(reg_num){
|
||||
case traits::NEXT_PC:
|
||||
tu("*next_pc = {:#x};", pc.val);
|
||||
break;
|
||||
case traits::PC:
|
||||
tu("*pc = {:#x};", pc.val);
|
||||
break;
|
||||
default:
|
||||
if(!tu.defined_regs[reg_num]){
|
||||
tu("reg_t* reg{:02d} = (reg_t*){:#x};", reg_num, reinterpret_cast<uintptr_t>(get_reg_ptr(reg_num)));
|
||||
tu.defined_regs[reg_num]=true;
|
||||
}
|
||||
tu("*reg{:02d} = {:#x};", reg_num, pc.val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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}<%}
|
||||
}
|
||||
if(fcsr != null) {%>
|
||||
value NaNBox16(tu_builder& tu, value NaNBox16_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 16)
|
||||
return tu.ext(NaNBox16_val, traits::FLEN, false);
|
||||
else {
|
||||
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 32, false))), traits::FLEN) ;
|
||||
return tu.ext((tu.bitwise_or(tu.shl(box, 16), NaNBox16_val)), traits::FLEN, false);
|
||||
}
|
||||
}
|
||||
value NaNBox32(tu_builder& tu, value NaNBox32_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 32)
|
||||
return tu.ext(NaNBox32_val, traits::FLEN, false);
|
||||
else {
|
||||
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 64, false))), traits::FLEN) ;
|
||||
return tu.ext((tu.bitwise_or(tu.shl(box, 32), NaNBox32_val)), traits::FLEN, false);
|
||||
}
|
||||
}
|
||||
value NaNBox64(tu_builder& tu, value NaNBox64_val){
|
||||
if(static_cast<uint32_t>(traits::FLEN) == 64)
|
||||
return tu.ext(NaNBox64_val, traits::FLEN, false);
|
||||
else {
|
||||
throw new std::runtime_error("tcc does not support Registers wider than 64 bits");
|
||||
auto box = tu.assignment(tu.logical_neg((tu.ext(0, 128, false))), traits::FLEN) ;
|
||||
return tu.ext((tu.bitwise_or(tu.shl(box, 64), NaNBox64_val)), traits::FLEN, false);
|
||||
}
|
||||
}
|
||||
<%}%>
|
||||
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} */
|
||||
compile_ret_t __${generator.functionName(instr.name)}(virt_addr_t& pc, code_word_t instr, tu_builder& tu){
|
||||
tu("${instr.name}_{:#010x}:", pc.val);
|
||||
vm_base<ARCH>::gen_sync(tu, PRE_SYNC,${idx});
|
||||
uint64_t PC = pc.val;
|
||||
<%instr.fields.eachLine{%>${it}
|
||||
<%}%>if(this->disass_enabled){
|
||||
/* generate console output when executing the command */<%instr.disass.eachLine{%>
|
||||
${it}<%}%>
|
||||
tu("print_disass(core_ptr, {:#x}, \"{}\");", pc.val, mnemonic);
|
||||
}
|
||||
auto cur_pc_val = tu.constant(pc.val, traits::reg_bit_widths[traits::PC]);
|
||||
pc=pc+ ${instr.length/8};
|
||||
gen_set_pc(tu, pc, traits::NEXT_PC);
|
||||
tu("(*cycle)++;");
|
||||
tu.open_scope();
|
||||
this->gen_set_tval(tu, instr);
|
||||
<%instr.behavior.eachLine{%>${it}
|
||||
<%}%>
|
||||
tu("(*icount)++;");
|
||||
tu("(*instret)++;");
|
||||
tu.close_scope();
|
||||
vm_base<ARCH>::gen_sync(tu, POST_SYNC,${idx});
|
||||
gen_trap_check(tu);
|
||||
return returnValue;
|
||||
}
|
||||
<%}%>
|
||||
/****************************************************************************
|
||||
* end opcode definitions
|
||||
****************************************************************************/
|
||||
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());
|
||||
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);
|
||||
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_trap_check(tu);
|
||||
return ILLEGAL_INSTR;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
|
||||
volatile CODE_WORD x = instr;
|
||||
instr = 2 * x;
|
||||
}
|
||||
|
||||
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, tu_builder& tu) {
|
||||
// we fetch at max 4 byte, alignment is 2
|
||||
enum {TRAP_ID=1<<16};
|
||||
code_word_t instr = 0;
|
||||
phys_addr_t paddr(pc);
|
||||
auto res = this->core.read(paddr, 4, reinterpret_cast<uint8_t*>(&instr));
|
||||
if (res != iss::Ok)
|
||||
return ILLEGAL_FETCH;
|
||||
if (instr == 0x0000006f || (instr&0xffff)==0xa001)
|
||||
return JUMP_TO_SELF;
|
||||
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, tu);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
template <typename ARCH> void vm_impl<ARCH>::gen_leave_trap(tu_builder& tu, unsigned lvl) {
|
||||
tu("leave_trap(core_ptr, {});", lvl);
|
||||