Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

More fixes towards v1.0#52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ThomasWaldmann merged 8 commits intomicropython:masterfromwnienhaus:fixes-for-v1
Oct 4, 2021

Conversation

@wnienhaus
Copy link
Collaborator

Some more fixes to move us towards being able to assemble all the currently skipped examples from the binutils-esp32ulp test suite (toresolve#49).

This PR contains a few fixes - felt it was easier to send them as one PR, than 1 PR per commit.

The commits are independent of each other and can be reviewed one by one. They contain commit messages explaining what they each fix. Each commit also has a reference to the issue it fixed in the relevant binutils-esp32ulp test.

The last commits enables the tests that can now pass because of the fixes. 2 more files to go.

Offsets specified as immediate values are given in bytes but theunderlying machine instruction needs a word offset. Thus, we needto convert immediate values to words by dividing by 4.This commit contributes to being able to eventually assemble theesp32ulp_all.s test from binutils-esp32ulp. It addresses this line:https://github.com/espressif/binutils-esp32ulp/blob/249ec34cc2c9574a86f3f86bbb175a863f988bcf/gas/testsuite/gas/esp32ulp/esp32/esp32ulp_all.s#L109
This was a previously untested and incorrectly handled case. Therewas already some offset manipulation to account for the extrainstructions for handling non-native conditions.Because of the way symbol offsets are calculated by py-esp32-ulp,namely that extra instructions are already included in the offsets,the relative distance to a forward lying label is 1 instruction toomuch. Or put another way, when expanding a jump into 2 instructionsthe "current offset" refers to the first instruction, while it'sonly the second instruction that jumps to the intended label, sothat difference must be accounted for.Thus, for symbols we need to always subtract 1 from the offset. Forimmediate values, we only subtract 1 for a backward jump.
binutil-esp32ulp accepts an undocumented 4th parameter for the ADCinstruction, even though this parameter is unused as per binutils'current code.This commit contributes to being able to eventually assemble theesp32ulp_all.s test from binutils-esp32ulp. It addresses this line:https://github.com/espressif/binutils-esp32ulp/blob/249ec34cc2c9574a86f3f86bbb175a863f988bcf/gas/testsuite/gas/esp32ulp/esp32/esp32ulp_all.s#L174
So far line parsing made many assumptions on the format of lines.This commit makes line parsing more flexible and tolerable todifferent formats.The change is in how labels are identified. Now any symbol thatis first on the line (excluding whitespace) and that is followeddirectly with a colon (:), will be identified as a label.Labels allow all characters that are valid for symbol names,including ._$.This commit contributes to being able to eventually assemble theesp32ulp_all.s test from binutils-esp32ulp. It addresses this line:[esp32ulp_all.s:2](https://github.com/espressif/binutils-esp32ulp/blob/249ec34cc2c9574a86f3f86bbb175a863f988bcf/gas/testsuite/gas/esp32ulp/esp32/esp32ulp_all.s#L2) (no space between colon and next character)and also this line: [esp32ulp_globals.s:92](https://github.com/espressif/binutils-esp32ulp/blob/249ec34cc2c9574a86f3f86bbb175a863f988bcf/gas/testsuite/gas/esp32ulp/esp32/esp32ulp_globals.s#L92) (label indented).
The last few commits/fixes allow these tests to now pass so we nolonger need to skip them.
iftarget.type==IMMortarget.type==SYM:
_bx.dreg=0
_bx.addr=get_abs(target)
_bx.addr=get_abs(target)iftarget.type==SYMelseget_abs(target)>>2# bitwise version of "// 4"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't get this.

If it is a symbol, it directly uses its value (absolute address) else it uses an immediate offset // 4?

Considering everything else in the opcode is the same, how does the cpu know what to do? like whether it is an offset or an absolute address?

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

In both cases what the machine instruction gets is an absolute address (not relative offset). The absolute address is either the address of a label, or an absolute address specified as immediate value.

What is different in the two cases is that the assembler instruction must take an address given in bytes, while the machine instruction needs to contain the address in words. Because in py-esp32-ulp we already track label addresses in words internally, we do not need to divide those symbol addresses by 4. But for immediate values we need to (see:https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html#note-about-addressing).

Does that make sense, or did I miss what you asked?

However... I did just discover one more case for the JUMP instruction, where we don't properly divide by 4. So this current logic is not 100% perfect. It appears to be that it's not only IMM values that must be divided by 4, but also symbol values that we internally label with the ABS type (as opposed to REL). Those ABS type symbols are defined by.set. So maybe the logic here should really be: Is what was given to us a relocatable thing (label) or not. If yes, use as is, if not divide by 4.

This logic is starting to look valid to me, the more I think about it. It should give the same result for the cases currently handled correctly, but also for the case of symbols defined with.set. It would requires a bit of a bigger change though, because of expression evaluation, which potentially uses multiple symbols that could have different types. So I will try and see how binutils-esp32ulp handles mixing symbols types, and likely a valid solution could be to consider the result of an expression to be a REL type if any symbols in the expression were of that type, otherwise consider the result to be an ABS type. And then use ABS and REL here rather than SYM and IMM to decide whether to divide by 4.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

thanks for explaining, please add a comment above this like:

# we track label addresses in 32bit words, but immediate values are in bytes and need to get divided by 4.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Maybe we could also have ABS1 (byte addresses), ABS4 (32bit word addrs), etc. so we better know what we have.

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

So, my last part about the REL vs ABS, I think is not relevant anymore. I believe that "one more case" I talked about above, is actually a bug in binutils-esp32ulp

I have now tested quite a bit more and stepped through binutils-esp32ulp a bit and found the following: whether the value (that was defined with.set) gets divided by 4 depends on whether the symbol is marked as "global" or not. If marked as global, then the value will be taken as-is, when not marked as global, the value will be divided by 4. I don't see how this could be intended behaviour.

The reason I started to get skeptical is that binutils-esp32ulp behaves correctly for JUMPS and JUMPR cases, as per description in the documentation:https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/ulp_instruction_set.html#note-about-addressing. The documentation shows an example, where values, which come from.set'ed symbols, should not be converted from bytes to words. So the fact that the JUMP instruction then tried to divide the value of the symbol by 4 (in the case I tried to fix) seems inconsistent.

I think the issues comes up in binutils-esp32ulp, depending on where the value is actually "filled-in" into the instruction. For non-global symbols, the value is already set during the assembly stage (as), while in the global case, the symbol value is only "filled in" during the linking stage (ld) - it's 0 in the instruction before that stage. The implementation of this logic in the assembler and linker differ.

So that means, I would not change anything in our implementation (other than adding the comment you suggested).

I might file a bug report to the binutils-esp32ulp project.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah, sounds strange, please file a bug.

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I filed a bug report now:espressif/binutils-esp32ulp#22

ThomasWaldmann reacted with thumbs up emoji
Using a regex to parse each line makes the code easier to readand reason about. It uses capture groups to extract the exactsubstrings we need, removing the need for extra whitespacetrimming and string splitting.Benchmarking showed that it even performs slightly better onthe ESP32, while raising the committed memory by only 64 extrabytes of memory compared with the previous algorithm(measured after garbage collect).
The comment clarifies that because we track label addresses in32bit words, but that immediate values are in bytes, the codeneeds to divide immediate values by 4, while leaving symbols(label) addresses as-is.
@wnienhaus
Copy link
CollaboratorAuthor

I have added the changes as new commits this time.

I will leave the JUMP instruction's SYM vs IMM handling as it is now, because as I described in one of the comments, I believe the "special case" I saw in one of the remaining test scripts from binutils-esp32ulp, is a bug in their implementation.

So after this PR is merged, there is only 1 more issue I think (I will create a new PR after this one is merged) before we can pass all the skipped bintutils-esp32ulp tests. (There are some cases I don't think we should cater for, or that we could discuss how to cater for, but I will describe that in the next PR).

@ThomasWaldmannThomasWaldmann merged commit02e94ba intomicropython:masterOct 4, 2021
@ThomasWaldmann
Copy link
Collaborator

Merged, thanks!

@wnienhauswnienhaus mentioned this pull requestOct 7, 2021
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@ThomasWaldmannThomasWaldmannThomasWaldmann left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

1.0.0 milestone

2 participants

@wnienhaus@ThomasWaldmann

[8]ページ先頭

©2009-2025 Movatter.jp