Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by edt

  1. I'm using a P16F877A in this case. I haven't seen any info about integer size support. I can drop the aggressive optimization since it doesn't seem to do much for me, anyway. It does look like a truncation of sorts, but it never gave warning it was generating bad code, and it works fine without aggressive opt.
  2. I'm seeing an aggressive optimization that doesn't look right. short x = 0x102; my_func((char)(x >> 8)); my_func((char)(x & 0x00FF)); (the implementation of my_func doesn't seem to matter) 10: short x = 0x102; 0006 3002 MOVLW 0x2 0007 1283 BCF 0x3, 0x5 0008 1303 BCF 0x3, 0x6 0009 00A1 MOVWF 0x21 000A 3001 MOVLW 0x1 000B 00A1 MOVWF 0x21 11: my_func((char)(x >> 8)); 000C 2003 CALL 0x3 12: my_func((char)(x & 0x00FF)); 000D 2003 CALL 0x3 Notice that the high byte clobbers the low in r0x21 and then the parameter for the second call is wrong (shouldn't have the same value for both calls).
  3. I never saw any documentation on it, but I noticed the PORTB pins don't read high right away on power-on. I'm not sure if it has to do with RBPU or not. It might be all the input pins. Anyway, you might be saving the value before it stabilizes and reading from the bad data. I bet if you put a 100us delay or so at the start, it'll fix your problem. If anyone knows if/where this is documented, feel free to speak up.
  4. edt

    Static Const

    BTW, I just found a request for this feature with another PICC compiler: SDCC Feature Request: Efficient const. Not really any new info, but since I haven't seen much usage of "static consts," I thought it would be helpful to see it from someone else. Maybe they explain it a bit better.
  5. edt

    Static Const

    #define is completely handled by the preprocessor, so all it can do is substitute text. Const definitions (static or not) must have a type, and since they're processed later, they work a bit better. For instance, you could#define MY_VAL 3 static const unsigned char MY_CONST = MY_VAL; #undefine MY_VAL but if you try it with #define MY_CONST MY_VAL it would actually evalute MY_VAL after you #undefined it. There's the same kind of text-substitution vs. syntax-checking issue between macros and inline functions. First off, "dereference" wasn't the right word there...I always get them confused. I meant "take the address of," but I think you understood that anyway. It's the prefix & as in "addr = &var", not the infix "bit = 0x08 & var". I haven't found a use for it myself, but I'm sure someone has/will. If the constant gets propagated and optimized out of existence, as I'd hoped it could, it wouldn't have an address. Either it would have to return NULL or some dummy value for the address, or it would have to disable the optimization for any values that need an address. The first option would be easier, but the second would be the most correct (and not too much harder since it's static and only needs to check one file at a time).
  6. edt

    Static Const

    the "static" modifier actually has two unrelated uses. Inside a function scope it means "persistent across calls" like you were saying, but when used in a global context it means "local to this source file." A static value is not globally accessible, so it's irrelevant to the linker. The const keyword should clue in the compiler to an opportunity for value propagation. AFAIK, a "static const" value could function identically to a #define except for two things: type safety, and an address. (I know a #define only uses text substitution, but the effect should be the same). Anyway, my point from the first post was that unless the value is dereferenced (with the & operator), I don't see any reason not to propagate the literal value all the way through to the instructions that use it and completely remove it from RAM and from any explicit data sections in ROM. Here's a better example of what I mean by propagation: 1: static const unsigned char MY_NUM = 3; 2: my_var += MY_NUM; movlw 0x3 addwf my_var The value 3 only exists in the movlw instruction, never in RAM, and it doesn't need to be fetched from a table somewhere in ROM. All I wanted was efficient type-checked constants, it wouldn't need to be with "static const," but it seemed like that should do what I want and I don't see any other syntax that would. I've been using #defines anyway, but I always had to use them when I was working in assembly and I've been wishing for something else.
  7. I tried that one out and there's no gain on SourceBoost C (for PIC16) on any optimization level. For code like that, I would expect this: result = (test ? 1 : 0) to do better, but it doesn't, either...
  8. I'd be pretty careful doing that. I worked on a project once where the #include dependencies had cycles in them, and it was a huge pain sorting it out. I don't know where your redefinition came from, but I can tell you if A includes B and B includes A, then you will probably get errors in A about missing definitions.
  9. I compared the RAM and ROM usage for both and they were identical (121 and 625, respectively). There's probably just nothing else it can optimize, but I wanted to make sure I was seeing it at its best. This is the least optimized code I've seen so far: 35: var1 = var2 = var3 = var4 = 0; 008E 01EA CLRF 0x6a 008F 11E3 BCF 0x63, 0x3 0090 01EB CLRF 0x6b 0091 1163 BCF 0x63, 0x2 0092 186A BTFSC 0x6a, 0 0093 1563 BSF 0x63, 0x2 0094 186A BTFSC 0x6a, 0 0095 0AEB INCF 0x6b, F 0096 01EC CLRF 0x6c 0097 10E3 BCF 0x63, 0x1 0098 186B BTFSC 0x6b, 0 0099 14E3 BSF 0x63, 0x1 009A 186B BTFSC 0x6b, 0 009B 0AEC INCF 0x6c, F 009C 1063 BCF 0x63, 0 009D 186C BTFSC 0x6c, 0 009E 1463 BSF 0x63, 0 Variable liveness analysis would save the 0x6b and 0x6c regs (reusing 0x6a). Copy propagation would get it down to 4 instructions. For bonus points, the compiler could recognize that each assignment is independent (after copy propagation) and optimize to: MOVLW 0xF0 ANDWF 0x63, 1 I actually put the assignments all on one line like that in the hopes it would help the compiler recognize that last optimization. Liveness analysis and copy propagation would help in lots of other scenarios, too.
  10. edt

    Static Const

    But with the ROM keyword, if it were supported yet, I think the single value will be placed in a specific data block in a predetermined ROM location and then read from ROM into a register for each reference to it. That's not what I want. I want that constant to be completely resolved into a literal before the linking stage just as if I had used #define. I do intend to use "static" because I don't want the linker to know that I named the constant. I only want it accessible from one source file to another through an #include, just like a #defined constant would be. The multiple "independent copies" of the constant are only a problem if each declaration reserves RAM or ROM instead of constant folding the value as I'd hoped.
  11. edt

    Static Const

    If data is "stored in ROM", then it will still have a separate data location in ROM and then be loaded from that location on every use, correct? I was aiming for a global type-checked constant that was always treated as a literal (and resolved before link-time). For example, I wanted this: 1: static const unsigned char MY_NUM = 5; ; (no instructions) 2: my_var = MY_NUM; movlw 5 movwf my_var without the value 5 being placed in any other RAM or ROM.
  12. I think you can get rid of the search path, but you need to add 'libc.picXX.lib' for either pic16 or pic18 to your project as a lib file.
  13. I've been using static const definitions in my C header files, and I just noticed they're all going into RAM. I expected these to stay only in compiler memory and to be put in the code as literals when they're necessary. Coming from assembly, I'm well aware of the differences between #define directives and const definitions, and I much prefer the typechecking etc. of consts, but perhaps I'm misusing 'static const'? Is this an enhancement for a future version or am I missing something?
  14. Can someone tell me what I should expect for the optimization levels in 6.60 unreg? I've gotten identical results with -O1 and -Oa. I can only guess either the aggressive level optimizations have been moved back to -O1 in 6.60 or possibly they are disabled until you register... I also noticed the MPLAB integration doesn't have an option for the aggressive level. I had to add '-Oa' to the 'additional options' field myself. Looking through the generated assembly, I've seen tons of missed opportunities for optimization, so I'd expect 'aggressive' would do something.
  • Create New...