From: Nicklas Bo J. <nbj...@gm...> - 2012-05-22 22:01:46
|
Thanks for the explanation. It's clear :) Out of curiosity, why are the pushes and pops in the example below? movw leaves r17:r14 unchanged. Do we simply push and pop all registers to be on the safe side and limited static analysis? llvm: define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) { ret i32 %z } asm: return32_arg2: push r14 push r15 push r16 push r17 movw r23:r22, r15:r14 movw r25:r24, r17:r16 pop r17 pop r16 pop r15 pop r14 On Tue, May 22, 2012 at 11:32 PM, Borja Ferrer <bor...@gm...>wrote: > Here you have a link that explains how registers are used: > www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_reg_usage > Testing a calling convention without knowing how it actually works is > going to be an insane task to do xD > > About your question, when you read that link all will become clear but > basically here is what's going on. Arguments are passed from r25 down to > r8, since in this case three 64bit args can't fit in those registers the > last argument is passed through the stack, so you get: > arg1 is in: r25-r18 > arg2 is in: r17-r10 > arg3 obviously doesn't fit in 2 register so it's all passed through the > stack, thats why you get those loads. Notice that the lowest part of the > argument is in Y+5 because in +4 and +3 is r29:r28 you just pushed and in > +2 +1 is the the return address that was pushed into the stack after the > call was performed. > > Another thing, you should add checks on the pushes and pops for the callee > saved registers so we're sure that they're being saved. > > > > 2012/5/22 Nicklas Bo Jensen <nbj...@gm...> > >> Perfect :) >> >> I'm moving on to calling convention and have started with return values. >> However I'm a bit unsure what the calling convention actually is. For >> example with my last test, called "return64_arg2" in the attached .ll file >> and the generated assembly in the .s file, is the correct thing happening >> and how it should be tested? Couldn't we have passed the arguments in the >> normal registers? I.e. r25:r2. >> >> If the arguments don't fit in the registers, do we always store the >> result in the same place in ram? >> >> >> On Mon, May 21, 2012 at 11:38 PM, Borja Ferrer <bor...@gm...>wrote: >> >>> Nice, so now you have the same test failures as me, they are caused >>> because we're using custom address space stuff in clang, dont worry about >>> those. Basically they fail because these tests are writing into address >>> space 1 which is flash data and that is forbidden in our target (remember >>> flash memory is readonly). >>> >>> The test cases you just commited look great :) To which ones are you >>> going to move on next? >>> >>> Yes, that code looks correct, where is the problem? >>> >>> >>> 2012/5/21 Nicklas Bo Jensen <nbj...@gm...> >>> >>>> Is the following generated code correct: >>>> >>>> LLVM: >>>> >>>> define i8 @return8_arg(i8 %x) { >>>> ret i8 %x >>>> } >>>> >>>> Generated: >>>> >>>> return8_arg: >>>> ret >>>> >>>> >>>> Something similar in .c compiling with avr-gcc gives a few pushes, >>>> loads and pops. >>>> >>>> On Mon, May 21, 2012 at 10:48 PM, Nicklas Bo Jensen <nbj...@gm... >>>> > wrote: >>>> >>>>> When adding those targets I only have 10 unexpected failures: >>>>> >>>>> Clang :: CodeGen/address-space-compound-literal.c >>>>> Clang :: CodeGen/address-space-field1.c >>>>> Clang :: CodeGen/address-space.c >>>>> Clang :: CodeGenCXX/mangle-address-space.cpp >>>>> Clang :: PCH/types.c >>>>> Clang :: Sema/address_spaces.c >>>>> Clang :: SemaCXX/address-space-conversion.cpp >>>>> Clang :: SemaCXX/address-space-newdelete.cpp >>>>> Clang :: SemaCXX/address-space-references.cpp >>>>> Clang :: SemaTemplate/address-spaces.cpp >>>>> >>>>> I will try to run each test separately and try to figure out why they >>>>> are failing. I have also attached the test output. >>>>> >>>>> I'm also committing tests for and, or and xor in a minute. They are >>>>> really simple and similar to the add and sub tests. Please review these :) >>>>> >>>>> >>>>> On Mon, May 14, 2012 at 11:32 PM, Borja Ferrer <bor...@gm...>wrote: >>>>> >>>>>> Did you try adding the x86 and x64 targets with the avr one? It's >>>>>> something related with an unsopported target. >>>>>> >>>>>> Good question, I think there's no need to do reg+imm for xor. >>>>>> >>>>>> Btw remember to add the SF mailing list so we can have a record ;) >>>>>> >>>>>> >>>>>> 2012/5/14 Nicklas Bo Jensen <nbj...@gm...> >>>>>> >>>>>>> Sorry, that is the llvm+clang trunk gives me 13 unsupported tests, >>>>>>> i.e. no failures versus the avr-llvm giving me 280 unexpected failures. >>>>>>> >>>>>>> >>>>>>> On Mon, May 14, 2012 at 9:08 PM, Nicklas Bo Jensen < >>>>>>> nbj...@gm...> wrote: >>>>>>> >>>>>>>> Hi, >>>>>>>> >>>>>>>> BTW, the newest llvm and clang trunk only gives me 13 unexpected >>>>>>>> failures compared to the the newest trunk with avr-llvm where i get 280 >>>>>>>> unexpected failures. >>>>>>>> >>>>>>>> Considering the regression tests for xor, does it make sense to >>>>>>>> test reg+imm, as the avr assembler does not have xor for immediate? >>>>>>>> >>>>>>>> >>>>>>>> On Thu, May 10, 2012 at 9:12 PM, Borja Ferrer < >>>>>>>> bor...@gm...> wrote: >>>>>>>> >>>>>>>>> I don't think so, but I configured llvm to support both x86 and >>>>>>>>> x64, so maybe that could help, in fact I can't build clang if I don't add >>>>>>>>> support for x86. >>>>>>>>> >>>>>>>>> >>>>>>>>> 2012/5/10 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>> >>>>>>>>>> Target: x86_64-unknown-linux-gnu >>>>>>>>>> >>>>>>>>>> But I only configured for avr... Did I do something wrong? >>>>>>>>>> >>>>>>>>>> On Thu, May 10, 2012 at 5:32 PM, Borja Ferrer < >>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>> >>>>>>>>>>> This is what I'm getting: >>>>>>>>>>> >>>>>>>>>>> Expected Passes : 9914 >>>>>>>>>>> Expected Failures : 66 >>>>>>>>>>> Unsupported Tests : 569 >>>>>>>>>>> Unexpected Failures: 11 >>>>>>>>>>> >>>>>>>>>>> I've seen in that file you attached that you're getting errors >>>>>>>>>>> because of the target triple, errors like: >>>>>>>>>>> >>>>>>>>>>> error: unable to create target: 'No available targets are compatible with this triple, see -version for the available targets.' >>>>>>>>>>> >>>>>>>>>>> or >>>>>>>>>>> >>>>>>>>>>> error auto-selecting target for module 'No available targets are compatible with this triple, see -version for the available targets >>>>>>>>>>> >>>>>>>>>>> so I guess that's the reason, so what is your target triple? do >>>>>>>>>>> clang -v to get it, mine is i386-pc-linux-gnu >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> 2012/5/10 Borja Ferrer <bor...@gm...> >>>>>>>>>>> >>>>>>>>>>>> Interesting, I'll check it out tomorrow to see if I can find >>>>>>>>>>>> some reason behind this, because we're getting very different results here. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> 2012/5/9 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>>>>> >>>>>>>>>>>>> Sorry for my slow response.Got i working again now, thanks. >>>>>>>>>>>>> >>>>>>>>>>>>> Building with optimization disabled and assertions turned on i >>>>>>>>>>>>> get: >>>>>>>>>>>>> >>>>>>>>>>>>> Avr llvm+clang: >>>>>>>>>>>>> Expected Passes : 6978 >>>>>>>>>>>>> Expected Failures : 39 >>>>>>>>>>>>> Unsupported Tests : 3281 >>>>>>>>>>>>> Unexpected Failures: 279 >>>>>>>>>>>>> >>>>>>>>>>>>> In the 279 unexpected failures for example 143 of them are >>>>>>>>>>>>> test/CodeGen/Generic. I'm not really sure how these tests are supposed to >>>>>>>>>>>>> work? None of them seems to be using FileCheck. >>>>>>>>>>>>> >>>>>>>>>>>>> However building for msp430 seems to be giving me similar >>>>>>>>>>>>> results, indicating that it is not a avr-llvm specific problem. Please see >>>>>>>>>>>>> the attached output "make check-all" from avr-llvm. >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Fri, May 4, 2012 at 11:30 PM, Borja Ferrer < >>>>>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> I'm asking because last week you said that you were getting >>>>>>>>>>>>>> +200 fails, and since I'm getting 11 I wanted to know what's going on. >>>>>>>>>>>>>> >>>>>>>>>>>>>> faluco is me btw, I updated a patch today because I got a >>>>>>>>>>>>>> conflict when updating my clang repo. These variables are defined in >>>>>>>>>>>>>> DiagnosticSemaKinds.td so check that you have them, they come from the >>>>>>>>>>>>>> flash.diff patch. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> 2012/5/4 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>>>>>>> >>>>>>>>>>>>>>> The new tests should pass. I cannot check other tests now, >>>>>>>>>>>>>>> I'm having some issues after applying the newest patches that came in today >>>>>>>>>>>>>>> by faluco: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> /home/nicklas/install/avr-llvm/llvm/tools/clang/lib/Sema/SemaDecl.cpp:4374:38: >>>>>>>>>>>>>>> error: >>>>>>>>>>>>>>> no member named 'err_flash_variable_requires_const' in >>>>>>>>>>>>>>> namespace >>>>>>>>>>>>>>> 'clang::diag' >>>>>>>>>>>>>>> Diag(NewVD->getLocation(), >>>>>>>>>>>>>>> diag::err_flash_variable_requires_const); >>>>>>>>>>>>>>> ~~~~~~^ >>>>>>>>>>>>>>> /home/nicklas/install/avr-llvm/llvm/tools/clang/lib/Sema/SemaDecl.cpp:4383:38: >>>>>>>>>>>>>>> error: >>>>>>>>>>>>>>> no member named 'err_flash_pointer_requires_const' in >>>>>>>>>>>>>>> namespace >>>>>>>>>>>>>>> 'clang::diag' >>>>>>>>>>>>>>> Diag(NewVD->getLocation(), >>>>>>>>>>>>>>> diag::err_flash_pointer_requires_const); >>>>>>>>>>>>>>> ~~~~~~^ >>>>>>>>>>>>>>> /home/nicklas/install/avr-llvm/llvm/tools/clang/lib/Sema/SemaDecl.cpp:7208:25: >>>>>>>>>>>>>>> error: >>>>>>>>>>>>>>> no member named 'err_flash_pointer_requires_const' in >>>>>>>>>>>>>>> namespace >>>>>>>>>>>>>>> 'clang::diag' >>>>>>>>>>>>>>> Diag(NameLoc, diag::err_flash_pointer_requires_const); >>>>>>>>>>>>>>> ~~~~~~^ >>>>>>>>>>>>>>> Have i done something wrong? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>> Nicklas >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, May 4, 2012 at 8:50 PM, Borja Ferrer < >>>>>>>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> How many tests failures are you getting now? >>>>>>>>>>>>>>>> I'm getting 11, 10 from clang due to address space stuff >>>>>>>>>>>>>>>> (you'll need to patch clang to get those) and 1 from llvm. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> 2012/5/4 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Ah, perfect. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I would actually guess that you need to run "make >>>>>>>>>>>>>>>>> check-all" before being able to test new tests individually. Sorry :) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Fri, May 4, 2012 at 8:17 PM, Borja Ferrer < >>>>>>>>>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Nevermind, got it. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> 2012/5/4 Borja Ferrer <bor...@gm...> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Thanks! >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> One thing, i dont have llvm-lit in that dir, am I >>>>>>>>>>>>>>>>>>> supposed to build llvm with an addtional param or something in order to get >>>>>>>>>>>>>>>>>>> it? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> 2012/5/4 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Ok, I've committed now. To only run the AVR specific >>>>>>>>>>>>>>>>>>>> tests run something like: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> ./build/Debug+Asserts/bin/llvm-lit >>>>>>>>>>>>>>>>>>>> llvm/test/CodeGen/AVR/ >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Fri, May 4, 2012 at 1:47 PM, Borja Ferrer < >>>>>>>>>>>>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Oh a small one I've just noticed, leave only 1 newline >>>>>>>>>>>>>>>>>>>>> between tests not 2. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> 2012/5/4 Borja Ferrer <bor...@gm...> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Ok they look great now, I don't have any other >>>>>>>>>>>>>>>>>>>>>> objections. Please commit this test to SVN, post your SF username here so >>>>>>>>>>>>>>>>>>>>>> that Eric or John can give you commit permissions. Once it gets commited >>>>>>>>>>>>>>>>>>>>>> I'll check if I need to add any pattern specific tests to it, these tests >>>>>>>>>>>>>>>>>>>>>> are corner cases of some instructions. >>>>>>>>>>>>>>>>>>>>>> Before commiting it, remove the testcases dir with >>>>>>>>>>>>>>>>>>>>>> all the files there, and create a new one called test/CodeGen/AVR, and >>>>>>>>>>>>>>>>>>>>>> place your file there, just to keep the same structure like in llvm's repo. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> About the rest of tests to do, from that list remove >>>>>>>>>>>>>>>>>>>>>> mul and division for now, mul isn't yet implemented and division can come >>>>>>>>>>>>>>>>>>>>>> later. Sub tests should be very similar to add, then add binary ops (or, >>>>>>>>>>>>>>>>>>>>>> and, xor). Add calling convention tests (argument passing through regs and >>>>>>>>>>>>>>>>>>>>>> stack, return values for each value type, calls). Memory operations, etc... >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> There are quite a few tests to add, but for now do >>>>>>>>>>>>>>>>>>>>>> the sub and binary op tests and we'll discuss the others by then. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> 2012/5/4 Nicklas Bo Jensen <nbj...@gm...> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> 1) Sure >>>>>>>>>>>>>>>>>>>>>>> 2) Yes, I've followed the msp430 backend that does >>>>>>>>>>>>>>>>>>>>>>> include it. I've removed it now. >>>>>>>>>>>>>>>>>>>>>>> 3) Again, I've moved the CHECK lines, but it differs >>>>>>>>>>>>>>>>>>>>>>> from backend to backend. >>>>>>>>>>>>>>>>>>>>>>> 4) Done >>>>>>>>>>>>>>>>>>>>>>> 5) Done >>>>>>>>>>>>>>>>>>>>>>> 6) Done >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> I will continue working other tests, which do we >>>>>>>>>>>>>>>>>>>>>>> need? Something like(and please add/comment): >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -Sub >>>>>>>>>>>>>>>>>>>>>>> -division(Only working for multiples of 2?) >>>>>>>>>>>>>>>>>>>>>>> -mult >>>>>>>>>>>>>>>>>>>>>>> -Return argument(In a few variants) >>>>>>>>>>>>>>>>>>>>>>> -and >>>>>>>>>>>>>>>>>>>>>>> -or >>>>>>>>>>>>>>>>>>>>>>> -xor >>>>>>>>>>>>>>>>>>>>>>> -increment >>>>>>>>>>>>>>>>>>>>>>> -branching? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Any ideas? >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Thanks, >>>>>>>>>>>>>>>>>>>>>>> Nicklas >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> On Wed, May 2, 2012 at 12:29 AM, Borja Ferrer < >>>>>>>>>>>>>>>>>>>>>>> bor...@gm...> wrote: >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> Obviously in the last line I meant adiw or >>>>>>>>>>>>>>>>>>>>>>>> subi/sbci pair, add for immediates doesn't exist for imms greater than 63 >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> 2012/5/2 Borja Ferrer <bor...@gm...> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> They look good, very nice :) >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Some small details and nitpicks: >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> 1) I think it's not necessary to add the >>>>>>>>>>>>>>>>>>>>>>>>> reg_reg_imm variant because you covered it with the other two tests. >>>>>>>>>>>>>>>>>>>>>>>>> 2) Do the tests work if you remove the target >>>>>>>>>>>>>>>>>>>>>>>>> triple line? I've seen other backends don't include it. >>>>>>>>>>>>>>>>>>>>>>>>> 3) Move the CHECK lines after the function >>>>>>>>>>>>>>>>>>>>>>>>> prototype like other backends do. >>>>>>>>>>>>>>>>>>>>>>>>> 4) In every CHECK line, can you remove the tabs >>>>>>>>>>>>>>>>>>>>>>>>> between the instr mnemonic and the first operand and add a single space? >>>>>>>>>>>>>>>>>>>>>>>>> (I'm unsure about this because i dont know if CHECK eats spaces). Also for >>>>>>>>>>>>>>>>>>>>>>>>> the future, the llvm coding standards says to config your editor to replace >>>>>>>>>>>>>>>>>>>>>>>>> tabs with spaces, so it's a good moment time to do it. >>>>>>>>>>>>>>>>>>>>>>>>> 5) Oh and the most important one, please add this >>>>>>>>>>>>>>>>>>>>>>>>> in only one file, add.ll or something like that, so we can keep this >>>>>>>>>>>>>>>>>>>>>>>>> convention in the future, otherwise we'll end having too many test files. >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> Something that should be covered is, when doing 16 >>>>>>>>>>>>>>>>>>>>>>>>> bit additions we can use adiw or add depending on the imm value, can you >>>>>>>>>>>>>>>>>>>>>>>>> cover this aswell? >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> 2012/5/1 John Myers <ato...@gm...> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> On Sun, Apr 29, 2012 at 10:46 AM, Nicklas Bo >>>>>>>>>>>>>>>>>>>>>>>>>> Jensen <nbj...@gm...> wrote: >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> Hi, >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> I have successfully been able to compile your >>>>>>>>>>>>>>>>>>>>>>>>>>> testcases (/avr-llvm/testcases/*.ll) to something looking like valid avr >>>>>>>>>>>>>>>>>>>>>>>>>>> assembler. >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> How should I test/simulate the assembler? I get >>>>>>>>>>>>>>>>>>>>>>>>>>> errors when trying to simulate the generated assembler in AVRStudio. >>>>>>>>>>>>>>>>>>>>>>>>>>> Perhaps they use a different assembler? >>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>> avr-llvm produces GNU assembler syntax, which is >>>>>>>>>>>>>>>>>>>>>>>>>> different then the Atmel assembler syntax. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>> Eventually we could support multiple asm syntax's >>>>>>>>>>>>>>>>>>>>>>>>>> like the X86 target does. >>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> > |