Page 1 of 2

ARM Overview Revert

Posted: Sun Feb 23, 2014 12:20 pm
by Pancakes
I was wondering why this section of the ARM Overview page was reverted.

http://wiki.osdev.org/index.php?title=A ... ldid=13278
Arbitrary Source On Internet wrote: ...This one always surprises everyone. Open the ARM architecture manual and try and find an integer division instruction. Go ahead, I’ll wait. Can’t find it? It’s normal. There is none. Yes, the ARM architecture has no hardware support for integer division, it must be performed in software. If you compile the following code:
It may be something that is wrong, but I could not find anything anywhere that stated why it was reverted. I think it is important that the reader be aware that the ARM architecture has no hardware division. It is odd because the entire section was removed instead of just removing the code.. perhaps the code was the problem?

If no one says anything I will just add the section back in because I am not sure why it was removed.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 12:38 pm
by iansjack
The fact that some ARM devices do have integer division instructions does indeed make the quote incorrect. So the mystery is why any of it was allowed to stand in its current form.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 2:14 pm
by Pancakes
iansjack wrote:The fact that some ARM devices do have integer division instructions does indeed make the quote incorrect.
I was finally able to come across this page http://www.linkedin.com/groups/ARM-core ... .242517259. It seems the hardware division was implemented around ARMv6 on the VFP hardware which is non-integer (floating point). Also, on some CPU it is implemented in thumb mode. And, then on some of the latest processor cores released it looks like it is supported in native mode.

I think we need that section. So I am going to reword it and hopefully give what I know. I hope some more people post here and contribute with what they know (or even go and edit the page) so it can be as accurate and informative as possible to anyone reading it. I want someone to not have to spend hours searching the web looking for the answer. I want them to do more with their time than I am able to so they can get further along and hopefully contribute back.

I am not saying anyone has done anything wrong. This is not directed at the previous poster but to everyone in general:
Look I do not know everything, and it makes me feel bad when I get something wrong not only personally but also the fact that I might confuse or make someone learn something wrong, BUT I am TRYING to help people learn about system programming. I really am devoting my spare time to try to make this place better. So, if you know something and you want to help out that would be great. If you are going to force me to research everything all by myself then I suppose you can easily win that and I am going to let you because I care about the guys who are going to think what a great page and how it really helped me out.

What I really want to say is I would feel better if this was more of a team effort to improve the wiki and everyone was chipping in a hand. You know even if it was a oh yeah buddy its implemented in thumb mode on some and normal mode on the latest processors. That would be a big help to me to cut down my own research time so I can do other things during the day, and it would make not only the forums but the wiki really awesome!

So it kind of feels like a slap in the face sometimes, because you know I am trying to make a great page where people do not have to spend hours banging their head trying to figure this stuff out and they can easily absorb it and continue onward and HOPEFULLY turn around and contribute back just like I did. I think some of you feel like the next guy should have to work just as hard as you did to learn what you did, but maybe (my opinion) you do not realize that if the entire world worked like that we would all be sitting in the stone age right now. The only reason we have the technology we have today (and the resources here at the website) is because it was a TEAM effort. No one single individual contributed all these tutorials, articles, how-to(s), and forum ports. If you figured out electromagnetism and decided that the next guy needed to work just as hard and he decided the same thing when he figured it out then the human race as a whole would be severely limited in it's potential. So if any of you think that the next guy needs to work just as hard as you then you have completely forgot about all the articles, forum posts, tutorials, and how-to(s) that YOU read that were written by someone else.

And, if one of you on these forums is so BADASS that you never used anyone else to learn what you know or get your foot in the door then you know what you need a special title attached to your forum name because you truly are bad @$$ and have my respect, and by god I will be amazed. I know myself and others have figured out some really amazing things by ourselves and we truly do need some credit (which we will never receive) for doing it. You know some stuff is not documented and does not exist on the internet (at least not anywhere easily findable). But, I myself could not have got this far with out help from someone else in the form of written or spoken information.

For the rest of you I would just appreciate a little help because you do not have a badass rank, and you know it never hurts to say, "Hey, btw thanks for trying to make the wiki better. Thanks for putting some time into this." I do not expect it because I have NEVER got it... not once. I am just trying to make a point that you know I am trying here to contribute, improve, and help. I know that I am making the right choice because there are guys out there that learn something and go on to improve on it, extend it, and ultimately get further than I have or will.


So if you know something about ARM processors and it only takes you a few minutes to throw it on here, edit the page (even if added a note on the talk page), then it would be appreciated. Either, I will compile it together or someone else will. If your afraid to post because you might have it wrong then just say it could be wrong. I am not going to be upset because someone made a mistake. I just want to get it fixed, resolved, corrected, and move forward.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 2:58 pm
by Combuster
Bit of a shame to come asking that two years later. Took me some time to figure out what really happened:

IOW, the code was utterly broken (and didn't even suggest using libgcc which would have been the proper solution), and I might have googled the other half which would obviously demonstrate the other key statement being false as well. So my guess is that I simply considered it noobism/vandalism followed by a full revert for being unsalvageable.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 3:09 pm
by Pancakes
Excellent, and thanks! Now, we can put a nice section in explaining the situation and how to work around it. I had pulled that code from somewhere that I can not remember and should have tested it before putting it up there. I just assumed it worked.

Btw, I do not appreciate your comment about how I am shameful. I think it is uncalled for, inappropriate, and unprofessional. Also I would like to kindly ask you to not to be so disrespectful to me.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 3:19 pm
by Pancakes
Also, Let me run this by anyone:

I think it would be nice to provide in the section (on the page) information about the options:

1. Link with libgcc

2. Implement them manually, either some source showing it or a link showing it as an example just for completeness (does not have to be the fastest or best, but just something you know to show someone who might be a little lost)

3. More detailed explanation about the older processors that did not support it and how the newer ones do. Just in case someone works with an older processor including one with support in the FSP, thumb, or native mode.

4. Also, a note (short sentence or two) about how (I assume most) cross-compilers by default will target the version of the ARM instruction set that does not include the native integer division. This is going to trip a lot of people up at the beginning, and I think it would be helpful for them to know that they can simply switch to a higher target machine to get the compiler to emit the instructions for native unsigned and signed integer divide.

What do you think?

<edit>
For the moment I have just linked to the forum post so someone at least has some direction. I feel like that is better than just leaving it completely blank as they can at least learn about how to resolve the problem and actually get some information about the problem.

http://wiki.osdev.org/index.php?title=A ... ldid=15592
</edit>

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 3:59 pm
by iansjack
Just to explain a bit, I have done a little ARM programming but I really know very little about ARM processors. But the quote that you reposted here seemed so extraordinary that I Googled it. My comment was the result of about 1 minutes research.

I think that if definitive statements are to be made then they deserve to be researched. That doesn't mean that I have the time or inclination to research ARM programming enough to make a meaningful contribution to the Wiki on the subject. i would rather keep quiet than post misinformation. Better to leave people to find out things for themselves than to tell them things that are wrong.

A link to the ARM manuals is fine as far as I'm concerned. Same goes for x86 programming; there certainly is a place in the forums for questions about some aspects of x86 programming but there is no need for the Wiki to explain it in detail. The manuals already do that.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 4:18 pm
by Pancakes
@iansjack

So is the proposal okay or the link to the forums? Or, should we just leave that out?

I feel like it is something that will cause most people some trouble and time when we could just basically summarize the problem at least. They are going to have to search the web you know, and if people search the web for everything then what good is the wiki is just what I am thinking.

Having some example code is up for grabs. I think it is a good idea. That code I had there was not very good for performance. I can not remember where I got it from, but I think it did at least show an example and maybe kind of left it up to the reader if they wanted to optimize it or come up with something better.

I do wish I would have known more about the problem when I wrote that or I would have put information about using the static library, and explained how some processors do and do not have support. But, you know just my opinion.

But, Yes I agree we should not duplicate an entire manual, and some of the information on that page does duplicate it, but I feel like we kind of achieved a nice balance of duplication and information. I kind of wrote it from the view point of someone who knows nothing about ARM but stumbles upon it and goes wow this looks pretty cool. I might want to checkout development for ARM. You know kind of give them a taste of the architecture instead of just a link to the manual. Also, I wanted some stuff there to keep someone who starts with ARM from being bogged down in various gotchas if you will. You know the divide problems, unaligned memory access, signed chars, interrupt/exception vectors being instructions not addresses, and likely some other things that could really confuse someone and cause them a lot of debugging.

Thanks for helping iansjake. My post was not about you, but was mainly due to my frustration with the revert and not understanding why it was completely removed. You know I figured it should at least deserve a sentence or two to help point someone in the right direction, and of course now with Combuster's help we have the forum thread linked so someone can at least have some light shed on the problem in a centralized location (no excessive searching, debugging, or experimenting).

But, yeah basically just had me so confused why you know someone just did not link that forum post in the first place unless you know I guess that problem is considered noobism/vandalism by people? LOL - What do you think about you or anyone else think about it being noobism? Maybe it is. Need some good input on this because I know Combuster really tries hard to help people and he apparently felt that it was wrong for it to be there, but like I said almost anyone with a default setup of a GCC cross-compiler (I think) is going to run into that problem if they try to do a divide.

Re: ARM Overview Revert

Posted: Sun Feb 23, 2014 6:59 pm
by Pancakes
I have spent a bit of time and have basically arrived at this function which is used in libgcc. So, basically, if someone does not want to link with libgcc for whatever reason. This code below is basically the optimized version of the subtraction loop which is basically what someone said in that post from a while back (they recommend to do). The code was actually not broken it is just that I never sat down and looked at the problem further because I was doing little divisions likely and was just wanting to give an example of how to implement the functions.

If you specify an architecture/machine to GCC and the ARM mode supports native division then the compiler should emit the sequence and not try to call the functions below. If you are in THUMB mode and you do a division then the compiler should emit the instructions if supported. The only other case you might worry about would be floating point instructions which (someone correct me if I am wrong) should be just as simple as actually doing them in C/C++ if your target machine/architecture supports them else it might try to call another function for software emulation. So linking to LIBGCC would really make sense because it should provide all those functions (the one below basically copied from LIBGCC).

I do not think LIBGCC will help the compiler in deciding to use FP operation for a INT operation if it was faster. I guess you just have to macro that up in your code. Not sure if you would even want too because I have not dug down into it.

But, if someone just wants to get their kernel, OS, system software, whatever up and running and does not want to link to LIBGCC for whatever reason then I think it is kind of cool to have this where it can be found and used.

Code: Select all

unsigned long udivmodsi4(unsigned long num, unsigned long den, int modwanted)
{
  unsigned long bit = 1;
  unsigned long res = 0;

  while (den < num && bit && !(den & (1L<<31)))
    {
      den <<=1;
      bit <<=1;
    }
  while (bit)
    {
      if (num >= den)
	  {
		num -= den;
		res |= bit;
	  }
      bit >>=1;
      den >>=1;
    }
  if (modwanted)
	return num;
  return res;
}

unsigned int __aeabi_uidiv(unsigned int num, unsigned int den) {
	return udivmodsi4(num, den, 0);
}

int __aeabi_idiv(int num, int den) {
	return udivmodsi4(num, den, 0);
}
Here is the old (said by some to be broken) code. I have to say technically it works, ROFL. It just is not the best way to do it.. Just can not believe someone just yanked it out with out putting in the better function above... *shugs*..

Code: Select all

CODE REMOVED (COMBUSTER EXPLAINED BELOW)
What do you guys think? Any mistakes? LOL

Re: ARM Overview Revert

Posted: Mon Feb 24, 2014 1:19 am
by Combuster
I have to say technically it works

Code: Select all

$ ./testabi 
10 / 3 = 3
10 / 3 = 12
I call a troll.

Re: ARM Overview Revert

Posted: Mon Feb 24, 2014 8:27 am
by sortie
@Pancakes: The rule about when to use libgcc is really simple:
All code compiled with gcc must be linked against libgcc.
The compiler will unconditionally assume it is present and emit calls to it if it feels like it. You cannot reliably compile code with gcc unless you link against it, it would be like commenting out a few functions from the compiler and hoping it still works. The good news is that libgcc is universally available, you simply have to build it along with your cross-compiler and link it in by passing -lgcc to the compiler link command (you'll need to link with your compiler rather than ld, but that's the usual way it is done anyways) (if you don't, it won't properly locate libgcc). It's that simple. It's also a static library, which means that if only the needed parts of it gets pulled in.

Do not go reinventing libgcc function by function. It's fragile (as you don't supply the full libgcc) and you'll likely get it wrong. It's also a waste of effort when it's so simple to pull it in properly. The compiler doesn't decide whether to use libgcc and whether to emit instructions directly (if libgcc isn't available): It is always available from the compiler point of view.

(If you are not satisfied with this, that's okay. I encourage you do modify the gcc source code such that no libgcc calls ever happen. Unless you do that, it's a bug not to link against it unless you have constructed proofs no libgcc call will ever happen and actually verified it is true in the gcc source code - and keep maintaining such proofs when new compiler revisions come out.)

Re: ARM Overview Revert

Posted: Mon Feb 24, 2014 8:32 am
by Brendan
Hi,
sortie wrote:@Pancakes: The rule about when to use libgcc is really simple:
All code compiled with gcc must be linked against libgcc.
I think my rules are different (I never use gcc or libgcc for OS code). 8)


Cheers,

Brendan

Re: ARM Overview Revert

Posted: Mon Feb 24, 2014 5:43 pm
by Pancakes
@Combuster
I was just testing everyone! ... LOL - No I am so stupid I did it again! I swear to god that block of code looks right to me every damn time. When will I learn to test something thoroughly! I HATE that code now.

Thanks again, Combuster.

@sortie
Good, I can include that into the wiki to help people understand why they would want to link to libgcc and any of it's dependencies.

I myself can not link to LIBGCC. My compiler (or maybe it was the linker) kept crashing. It is a bug apparently. So in order to keep from wasting too much time trying to figure all that out and keep going working on my project I just manually solved the link time dependencies for LIBGCC. Yep, it can easily break, but I can afford to deal with it later and it should break in a way that I can catch the problem fairly quickly - I hope.

I think it is educational giving people the insight into exactly how the software implementation of some operations work. You know if LIBGCC was somehow automatically included in the link stage then a bet a whole bunch of people would never realize that on some machine/architectures the divide has to be done in software. Let alone realize to change the machine/architecture flag for the compiler so it emits the native instructions if supported.

But, I will word the section where it strongly advises against trying to implement LIBGCC if at all possible.

Thank you for helping me with the wiki (and my own personal knowledge) sortie!

Re: ARM Overview Revert

Posted: Tue Feb 25, 2014 5:01 am
by sortie
Hi Pancakes,

Allow me to clear up some of your misunderstandings:

libgcc doesn't have any dependencies (as far as I know, might be different on ARM, but I would be surprised. Let me know if I am wrong here). You should immediately fix your toolchain if it is unable to link against libgcc, the error may be worse than that (start a topic or something if you need help). Note how libgcc is compiler revision and command line option specific (ARM usually has a few different kinds of libgccs), whatever effort you invest into poorly cloning it is fragile and perhaps worthless if the next compiler release changes things. Note how libgcc is linked by default, but you explicitly disabled it by passing -nodefaultlibs (implied by -nostdlib) and thus promising to link it in manually. libgcc does considerably more than just division instructions, though that's the most notable operation provided. Other runtime features and shared code is provided there, though.

Re: ARM Overview Revert

Posted: Tue Feb 25, 2014 10:54 am
by Pancakes

Code: Select all

arm-linux-gnueabi-ld: warning: libc.so.6, needed by /usr/arm-linux-gnueabi/lib/libgcc_s.so, not found (try using -rpath or -rpath-link)
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `abort@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `raise@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `malloc@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `realloc@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `memcpy@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `free@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `memset@GLIBC_2.4'
/usr/arm-linux-gnueabi/lib/libgcc_s.so: undefined reference to `calloc@GLIBC_2.4'
Do not ask me, LOL. I am no expert on LIBGCC. But, I did a little reading and the _s means shared version. But, I have not been able to find a static copy. I could likely compile one or somehow find some flags to link that one static.. I dunno. I am not sure what the real problem is. I just do not want to spend all day on it when I can just plop in the needed division functions and keep going.


Yes, I know what that means but when a problem does happen its not going to be the end of the world. Sure LIBGCC is fragile, but its not going to melt my computer into the floor when it messes up, and it is highly unlikely its going to mess up in such as a way that creates this super hidden bug that is hard to find. So I am not worried about LIBGCC, right now.


But, I appreciate your help in giving information about this stuff! I will include it in the wiki page because I might not want to use LIBGCC (right this moment), but anyone reading the page deserves to know the truth and that is that LIBGCC is mandated when using GCC, can be highly fragile because it can change at any moment through compiler changes and target changes, and trying to re-implement it in it's entirety is just a waste of time unless its something someone finds fun to do.