[rust-dev] Cross-compilation with plugins is effectively dead?

2015-01-10 Thread Vladimir Pouzanov
I have some concerns related to
https://github.com/rust-lang/rust/issues/18699 and I'd like to get some
advice from the team.

Support for cross-compiling code with plugins was broken for a few months
now for anything but linux. Finally it seems to be broken for linux as well
halting all our efforts.

How important is cross-compilation support for rust at all? zinc is barely
the only embedded project based on rust but we do use plugins and macros
extensively throughout the code and we can't just stop using them,
unfortunately; so for us any breakage of plugins system is a halt. We can
deal with internal libs changing syntax but fixing up compiler itself is
not that easy.

Any chance we'll see it fixed before 1.0 hits?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Declaring the API unsafe while keeping the internal safety checks

2015-01-02 Thread Vladimir Pouzanov
Well, strictly speaking it *is* memory safety, as it all gets down to an
unsafe volatile store. Although I think I extend the 'unsafety' a bit by
considering code that can cause CPU to halt as unsafe too.

On Fri, Jan 2, 2015 at 2:11 AM, Kevin McGuire  wrote:

> Yes unsafe is primarily for memory safety. However! Your idea is good. It
> would be really good if you could have something like that. I am just not
> sure what the best way to do it is. It could be done by an attribute and
> lint with the ability to toggle it off with a module level, function level,
> or scope level second attribute, lol, possibilities are endless.
>
> But indeed unsafe is likely only, currently, for memory safety.
>
> Still I like the idea! I love the idea. I read your email earlier today
> but only shortly ago I realize what you mean.
> On Jan 1, 2015 5:17 AM, "Vladimir Pouzanov"  wrote:
>
>> I had this idea for some time and I'd like to discuss it to see if it is
>> something reasonable to be proposed for rust to implement or there are
>> other ways around the problem.
>>
>> Let's say I have a low level function that manipulates the hardware clock
>> using some platform-specific argument. Internally this function will do an
>> unsafe volatile mem write to store value in the register, but this is the
>> only part of the code that is unsafe compiler-wise, whatever else is in
>> there in the function is safe and I want the compiler to warn me if any
>> other unsafe operation happens.
>>
>> Now, given that this function is actually unsafe in terms of its realtime
>> consequences (it does not do any validation of the input for speed) I want
>> to mark it as unsafe fn and make a safer wrapper for end users, while
>> keeping this for the little subset of users that will need the actual speed
>> benefits.
>>
>> Unfortunately, marking it unsafe will now allow any other unsafe
>> operation in the body of the function, when what I wanted is just to force
>> users of it to be aware of unsafety via compiler validation.
>>
>> A safe {} block could have helped me in this case. But is it a good idea
>> overall?
>>
>> Some pseudo-code to illustrate
>>
>> pub unsafe fn set_clock_mode(mode: uint32) {
>>   // ...
>>   // doing some required computations
>>   // this code must be 'safe' for the compiler
>>   unsafe {
>> // ...
>> // writing the value to mmaped register, this one is unsafe but
>> validated by programmer
>>   }
>> }
>>
>> pub fn set_clock_mode_safe(mode: uint32) -> bool {
>>   // ...
>>   // validate input
>>   unsafe {
>> // I want this call to require unsafe block
>> set_clock_mode(mode);
>>   }
>> }
>>
>> --
>> Sincerely,
>> Vladimir "Farcaller" Pouzanov
>> http://farcaller.net/
>>
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Declaring the API unsafe while keeping the internal safety checks

2015-01-01 Thread Vladimir Pouzanov
Sounds reasonably simple, thanks for the idea!

On Thu, Jan 1, 2015 at 11:46 AM, Manish Goregaokar 
wrote:

> It should be reasonably easy to write a lint as a compiler plugin such
> that the following function:
>
> #[unsafe_specific]
> unsafe fn foo () {
>  #[allowed_unsafe] { // or just #[allow(unsafe_something_something)]
>   // do unsafe things here
>  }
>  // no unsafe blocks or functions allowed here.
> }
>
> would not compile with any unsafe code in the latter half of the function.
>
> Alternatively:
>
> unsafe fn foo() {
>  fn bar() {
>   unsafe {
> // unsafe stuff here
>   }
>   // no unsafe stuff here
>  }
>  bar();
> }
>
> -Manish Goregaokar
>
> On Thu, Jan 1, 2015 at 4:47 PM, Vladimir Pouzanov 
> wrote:
>
>> I had this idea for some time and I'd like to discuss it to see if it is
>> something reasonable to be proposed for rust to implement or there are
>> other ways around the problem.
>>
>> Let's say I have a low level function that manipulates the hardware clock
>> using some platform-specific argument. Internally this function will do an
>> unsafe volatile mem write to store value in the register, but this is the
>> only part of the code that is unsafe compiler-wise, whatever else is in
>> there in the function is safe and I want the compiler to warn me if any
>> other unsafe operation happens.
>>
>> Now, given that this function is actually unsafe in terms of its realtime
>> consequences (it does not do any validation of the input for speed) I want
>> to mark it as unsafe fn and make a safer wrapper for end users, while
>> keeping this for the little subset of users that will need the actual speed
>> benefits.
>>
>> Unfortunately, marking it unsafe will now allow any other unsafe
>> operation in the body of the function, when what I wanted is just to force
>> users of it to be aware of unsafety via compiler validation.
>>
>> A safe {} block could have helped me in this case. But is it a good idea
>> overall?
>>
>> Some pseudo-code to illustrate
>>
>> pub unsafe fn set_clock_mode(mode: uint32) {
>>   // ...
>>   // doing some required computations
>>   // this code must be 'safe' for the compiler
>>   unsafe {
>> // ...
>> // writing the value to mmaped register, this one is unsafe but
>> validated by programmer
>>   }
>> }
>>
>> pub fn set_clock_mode_safe(mode: uint32) -> bool {
>>   // ...
>>   // validate input
>>   unsafe {
>> // I want this call to require unsafe block
>> set_clock_mode(mode);
>>   }
>> }
>>
>> --
>> Sincerely,
>> Vladimir "Farcaller" Pouzanov
>> http://farcaller.net/
>>
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Declaring the API unsafe while keeping the internal safety checks

2015-01-01 Thread Vladimir Pouzanov
I had this idea for some time and I'd like to discuss it to see if it is
something reasonable to be proposed for rust to implement or there are
other ways around the problem.

Let's say I have a low level function that manipulates the hardware clock
using some platform-specific argument. Internally this function will do an
unsafe volatile mem write to store value in the register, but this is the
only part of the code that is unsafe compiler-wise, whatever else is in
there in the function is safe and I want the compiler to warn me if any
other unsafe operation happens.

Now, given that this function is actually unsafe in terms of its realtime
consequences (it does not do any validation of the input for speed) I want
to mark it as unsafe fn and make a safer wrapper for end users, while
keeping this for the little subset of users that will need the actual speed
benefits.

Unfortunately, marking it unsafe will now allow any other unsafe operation
in the body of the function, when what I wanted is just to force users of
it to be aware of unsafety via compiler validation.

A safe {} block could have helped me in this case. But is it a good idea
overall?

Some pseudo-code to illustrate

pub unsafe fn set_clock_mode(mode: uint32) {
  // ...
  // doing some required computations
  // this code must be 'safe' for the compiler
  unsafe {
// ...
// writing the value to mmaped register, this one is unsafe but
validated by programmer
  }
}

pub fn set_clock_mode_safe(mode: uint32) -> bool {
  // ...
  // validate input
  unsafe {
// I want this call to require unsafe block
set_clock_mode(mode);
  }
}

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Problems cross-compiling to ARM9

2015-01-01 Thread Vladimir Pouzanov
FWIW, we're just disabling segmented stack in zinc for now exactly because
of the same problem. I have a patch for llvm but I didn't really push it
upstream hard enough.

On Tue, Dec 30, 2014 at 11:23 AM, Valerii Hiora 
wrote:

> Hi Tomi,
>
> > Anyone have any idea if that's a larger problem, or simply something
> > nobody has written the small handcoded ASMs needed for ARMv5 or v4?
> > If latter, I might be able to wrap my head around this.
>
>   The problem you've got is related to segmented stack support. It need
> fix on 2 levels:
>
> - Rust - can be relatively easy fixed by providing (or patching) a
> target and marking it as a target which doesn't support segmented
> stacks, see example [1]
>
>Once it works you can play a bit to provide a correct implementation
> in record_sp.S and morestack.S
>
> - LLVM - as I remember some time ago LLVM generated a function prologue
> which uses the same instruction for any ARM device, may be that was
> patched in upstream, may be not. You can also ask Vladimir Pouzanov and
> zinc.rs [2] team, AFAIK they had the similar problem too and definitely
> have a workaround.
>
> [1]
>
> https://github.com/rust-lang/rust/blob/master/src/librustc_back/target/arm_apple_ios.rs#L33
> [2]  https://zinc.rs/
>
> --
>
>   Valerii
>
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Programmaticaly accessing compiler warnings

2014-11-01 Thread Vladimir Pouzanov
Hi all.

Is there any way to access compiler warnings and errors other than parsing
stdout? I'd prefer a bit more structured approach.


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A shiny test framework

2014-07-23 Thread Vladimir Pouzanov
On Wed, Jul 23, 2014 at 6:27 PM, Brian Anderson 
wrote:

> I assume this translates to `#[test]` fns under the hood?
>

Exactly. That actually complicates `context` support a bit, as shiny needs
to create nested modules. That would require forwarding all the views into
child modules (as they are transparent for end developer).

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
One note on why there's no after_each:

You cannot really make sure that the epilogue is being called, so if you
need to do anything after your test case, use RAII in before_each.


On Tue, Jul 22, 2014 at 8:10 PM, Benjamin Gudehus 
wrote:

> Nice to see an RSpec-like test framework and Hamcrest assertions/matchers
> for Rust!
>
>
> On Tue, Jul 22, 2014 at 9:09 PM, Ilya Dmitrichenko <
> errordevelo...@gmail.com> wrote:
>
>> Dude, that's pretty much rspec ;) sweet!
>> On 22 Jul 2014 20:07, "Vladimir Pouzanov"  wrote:
>>
>>> I've just published a tiny test framework: shiny at
>>> https://github.com/farcaller/shiny. It's best used with hamcrest-rust.
>>>
>>> This library exists because I find it ugly to redefine all the
>>> initialisation code in every test case and I can't simply move it to a
>>> function due to problems with moving [T] out.
>>>
>>> Here's how shiny looks:
>>>
>>> #[cfg(test)]
>>> mod test {
>>>   describe!(
>>> before_each {
>>>   let awesome = true;
>>> }
>>>
>>> it "is awesome" {
>>>   assert!(awesome);
>>> }
>>>
>>> it "injects before_each into all test cases" {
>>>   let still_awesome = awesome;
>>>   assert!(still_awesome);
>>> }
>>>   )
>>> }
>>>
>>> --
>>> Sincerely,
>>> Vladimir "Farcaller" Pouzanov
>>> http://farcaller.net/
>>>
>>> ___
>>> Rust-dev mailing list
>>> Rust-dev@mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A shiny test framework

2014-07-22 Thread Vladimir Pouzanov
I've just published a tiny test framework: shiny at
https://github.com/farcaller/shiny. It's best used with hamcrest-rust.

This library exists because I find it ugly to redefine all the
initialisation code in every test case and I can't simply move it to a
function due to problems with moving [T] out.

Here's how shiny looks:

#[cfg(test)]
mod test {
  describe!(
before_each {
  let awesome = true;
}

it "is awesome" {
  assert!(awesome);
}

it "injects before_each into all test cases" {
  let still_awesome = awesome;
  assert!(still_awesome);
}
  )
}

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] What do I do if I need several &muts into a struct?

2014-06-16 Thread Vladimir Pouzanov
I have a problem figuring the reasonable data access pattern for my code,
here's a brief description. I have a tree structure where each node has a
path and an optional name. Path is used to locate the node in tree
hierarchy, names are stored in a flat namespace as node aliases:

lpx17xx@mcu {
  clock {
attr = "value";
  }
}

os {
  thread {
entry = "start";
ref = &lpx17xx;
  }
}

this tree has 4 nodes, /mcu, /mcu/clock, /os and /os/thread. /mcu is also
known as "lpx17xx". I use the following structure to hold root nodes:

#[deriving(Show)]
pub struct PlatformTree {
  nodes: HashMap>,
  named: HashMap>,
}

Everything works fine up to the point of references. References allow some
nodes to modify other nodes. So, the first pass — I parse that snippet into
PlatformTree/Nodes struct. Second pass — I walk over the tree and for each
reference I invoke some handling code, e.g. in the handler of thread node
it might add some attribute to lpx17xx node. Which is not really possible
as it's in immutable Gc box. Also, such modifications are performed through
`named` hashmap, so I can't even store &muts in `nodes`, as I still can
store only immutable pointers in `named`.

How would you solve this problem?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Flatten a tree into HashMap, how do I pass a &mut around?

2014-06-15 Thread Vladimir Pouzanov
After a few hints on IRC I managed to simplify it to:

fn collect_node_names(&self, map: &mut HashMap>,
nodes: &Vec>) -> bool {
  for n in nodes.iter() {
if !self.collect_node_names(map, &n.subnodes) {
  return false;
}

match n.name {
  Some(ref name) => {
if map.contains_key(name) {
  self.sess.span_diagnostic.span_err(n.name_span, format!(
  "duplicate `{}` definition", name).as_slice());

  self.sess.span_diagnostic.span_warn(
  map.get(name).name_span,
  "previously defined here");
  return false;
} else {
  map.insert(name.clone(), *n);
}
  },
  None => (),
}
  }
  true
}

My failure point was that I didn't realise you cannot access &mut while yo
have a reference to anything you pass &mut to.


On Sun, Jun 15, 2014 at 8:14 AM, Vladimir Pouzanov 
wrote:

> I have a tree of Nodes where each node might have a name. I'm trying to
> convert the tree into a HashMap of named nodes, but my code is getting
> extremely complex due to the fact that I cannot pass &mut HashMap around.
>
> let mut named_nodes = HashMap::new();
> let nodes = vec!( ... );
> named_nodes = self.collect_node_names(&named_nodes, &nodes);
> println!('{}', named_nodes);
>
> fn collect_node_names(&self, map: &HashMap>,
> nodes: &Vec>) -> HashMap> {
>   let mut local_map: HashMap> = HashMap::new();
>   for (k,v) in map.iter() {
> local_map.insert(k.clone(), *v);
>   }
>   for n in nodes.iter() {
> for (k,v) in self.collect_node_names(&local_map, &n.subnodes).iter() {
>   local_map.insert(k.clone(), *v);
> }
> match n.name {
>   Some(ref name) => {
> if local_map.contains_key(name) {
>
> } else {
>   local_map.insert(name.clone(), *n);
> }
>   },
>   None => (),
>  }
>   }
>   local_map
> }
>
> this one works, but it's bloated and slow. Any hints on how to improve the
> code?
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Flatten a tree into HashMap, how do I pass a &mut around?

2014-06-15 Thread Vladimir Pouzanov
I have a tree of Nodes where each node might have a name. I'm trying to
convert the tree into a HashMap of named nodes, but my code is getting
extremely complex due to the fact that I cannot pass &mut HashMap around.

let mut named_nodes = HashMap::new();
let nodes = vec!( ... );
named_nodes = self.collect_node_names(&named_nodes, &nodes);
println!('{}', named_nodes);

fn collect_node_names(&self, map: &HashMap>,
nodes: &Vec>) -> HashMap> {
  let mut local_map: HashMap> = HashMap::new();
  for (k,v) in map.iter() {
local_map.insert(k.clone(), *v);
  }
  for n in nodes.iter() {
for (k,v) in self.collect_node_names(&local_map, &n.subnodes).iter() {
  local_map.insert(k.clone(), *v);
}
match n.name {
  Some(ref name) => {
if local_map.contains_key(name) {

} else {
  local_map.insert(name.clone(), *n);
}
  },
  None => (),
}
  }
  local_map
}

this one works, but it's bloated and slow. Any hints on how to improve the
code?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Nightly docs for Dash

2014-06-14 Thread Vladimir Pouzanov
Funnily enough I did the same yesterday. I made a small extension to
https://github.com/indirect/dash-rust, my fork can be found here:
https://github.com/farcaller/dash-rust

It removes the left side navigation panel from docs and adds TOC generation.


On Sat, Jun 14, 2014 at 2:55 AM, Valerii Hiora 
wrote:

> Hi,
>
>   Being a big fan of offline documentation I've prepared a fresh docset
> for Dash (zeal, helm-dash, any other compatible software).
>
>   Here is the link for subscription:
>
> dash-feed://https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fnet.
> vhbit.rust-doc%2FRustNightly.xml
>
>It's a beta and has a couple of known issues in it. If there would be
> enough interest - it could be also integrated with existing buildbots.
>
> --
>
>   Valerii
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] how is Rust bootstrapped?

2014-06-09 Thread Vladimir Pouzanov
Rustc runs on arm just fine.


On Mon, Jun 9, 2014 at 11:32 AM, Kevin Cantu  wrote:

> Perl and Python may still be dependencies for small things on some
> platforms, IIRC, too.
>
> Anyways, to get `rustc` on a new architecture, it must be one LLVM
> supports, and then you should cross-compile `rustc` onto it.  I don't
> remember for sure whether `rustc` even runs on ARM, or if people just
> cross-compile binaries for it, actually, though...
>
>
> Kevin
>
>
> On Mon, Jun 9, 2014 at 3:16 AM, Leo Testard  wrote:
>
>> Hello,
>>
>> The OCaml compiler is not used anymore for years. As you said, the Rust
>> build system now downloads a precompiled snapshot of the new
>> implementation, which is written in Rust. Unfortunately, you won't be able
>> to compile it yourself.if you don't have Rust already setup on your machine.
>>
>> For C++, I believe it's used to compile the modified LLVM Rustc uses.
>> Others may confirm this.
>>
>> Leo
>> --
>> Envoyé de mon téléphone Android avec K-9 Mail. Excusez la brièveté.
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I bootstrap rust form armhf?

2014-06-06 Thread Vladimir Pouzanov
Thanks, I managed to bootstrap my rustc already with a few hints.


On Fri, Jun 6, 2014 at 4:19 PM, Valerii Hiora 
wrote:

> I'm trying to run rustc on an arm board, but obviously there's no
>> precompiled stage0 to build the compiler.
>> Is there a procedure to cross-compile stage0 on other host machine where
>> I do have rustc?
>>
>
>Disclaimer: haven't tried anything like this, but just a couple of
> hints:
>
>- configure script checks for CFG_ENABLE_LOCAL_RUST, so it should be
> possible to use any rustc
>- in src/etc there are make_snapshot.py, snapshot.py, local_stage0.sh
> which might be useful for study
>- there are a couple of mentions of cfg(stage0) in sources, probably
> compiling rust for stage0 will require additionally setting --cfg stage0
>
> --
>
>Valerii
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] How do I bootstrap rust form armhf?

2014-06-04 Thread Vladimir Pouzanov
I'm trying to run rustc on an arm board, but obviously there's no
precompiled stage0 to build the compiler.

Is there a procedure to cross-compile stage0 on other host machine where I
do have rustc?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-05-01 Thread Vladimir Pouzanov
Is there any good reason why kSplitStackAvailable is hard-coded to 256
(given that I have tasks with their whole stack on 512 bytes)? I guess,
this constant should actually be externally configurable.


On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton  wrote:

> The prologue is run on every single function executed in a program, so
> I believe that in the hopes of keeping it as light as possible it
> never makes any function calls.
>
> I do agree though, that it's at tricky situation in that case. How
> does TLS otherwise work for that platform?
>
> On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov 
> wrote:
> > I have a side question related to the same code.
> >
> > Currently __STACK_LIMIT is constant, but I would like the preamble to
> verify
> > stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend
> on
> > the current running thread. Is there any reason, why it's not a function?
> > Any objections if I do some refactoring and make it a function? For a
> simple
> > case that could be a weak symbol that returns a constant.
> >
> >
> > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton  wrote:
> >>
> >> I agree with Corey, it's much better to send it upstream first. I'd be
> >> more than willing to help you out with writing tests or taking a peek
> >> at the patch if you want! I'm acrichto on IRC
> >>
> >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >> wrote:
> >> > The problem is that mrc is generated unless target is thumb1, but
> >> > cortex-m3
> >> > is thumb2 that still doesn't support mrc:
> >> >
> >> >
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
> ,
> >> > so an additional check to ST->TargetTriple.Data is required to verify
> >> > it's
> >> > not thumbv7m.
> >> >
> >> > Do I need to submit patch against https://github.com/rust-lang/llvmor
> >> > send
> >> > it to upstream?
> >> >
> >> >
> >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >> > wrote:
> >> >>
> >> >> Hm, it seems to have precautions to stop mrc from materializing on
> >> >> Thumb1.
> >> >> I guess I need to take a better look into what's going wrong on my
> >> >> side.
> >> >> I'll see what I can do with that.
> >> >>
> >> >>
> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton 
> >> >> wrote:
> >> >>>
> >> >>> The split stack patches for ARM were recently upstreamed, and they
> >> >>> were modified when being upstreamed as well. Primarily the location
> of
> >> >>> the split stack is no longer at a magic address for thumb, but
> rather
> >> >>> it uses the same instruction as ARM (some thumb processors do indeed
> >> >>> have the coprocessor). More information is in the long thread
> starting
> >> >>> at the initial attempt to upstream [1].
> >> >>>
> >> >>> For now you'll have to use no_split_stack because the thumb split
> >> >>> stack will always use a coprocessor, but I'm sure that the upstream
> >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack
> support
> >> >>> (I'd also be willing to help). You can find the initial commit for
> >> >>> support at rust-lang/llvm [2].
> >> >>>
> >> >>> [1] -
> >> >>>
> >> >>>
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
> >> >>> [2] - https://github.com/rust-lang/llvm/pull/4
> >> >>>
> >> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov
> >> >>> 
> >> >>> wrote:
> >> >>> > Starting recently (no more than two weeks), rustc is generating a
> >> >>> > broken
> >> >>> > prologue for arm. Here's the sample assembly:
> >> >>> >0x0f44 <+0>: push {r4, r5}
> >> >>> > => 0x0f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3}
> >> >>> >0x0f4a <+6>: mov r5, sp
> >> >>> >0x0f4c <+8>: b.n 0xa78 
> >> >>> >0x0f4e <+10>

Re: [rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
Ok, seems that I found a reasonably good solution.

The "app" is now an rlib, and the actual staticlib app that gets linked is
a wrapper, that sources all external crates and re-exports required symbols
like this:

#[no_split_stack]
#[no_mangle]
#[start]
pub extern fn main() {
  app::main();
}

I also had to move __STACK_LIMIT into external C file, as I couldn't define
it as external in one crate and provide it in another crate down the chain.


On Wed, Apr 30, 2014 at 5:29 PM, Vladimir Pouzanov wrote:

> Right, so I have a publicly reachable symbol __STACK_LIMIT inside my
> libzinc rlib:
>
> #[no_mangle]
> pub static mut __STACK_LIMIT: u32 = 0;
>
> which is present in rlib's object file:
>
> % arm-none-eabi-nm zinc.o|grep __STACK_LIMIT
>  B __STACK_LIMIT
>
> Now, I compile my application, which is a staticlib, emiting an obj (I
> could change staticlib to binary, that doesn't really change anything at
> this emit level):
>
> rustc -Z no-landing-pads -C relocation_model=static --target
> thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj
> -L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs
>
> Which implicitly links to libzinc-de5e5c68-0.0.rlib.
>
> Given the lto nature, ./build/intermediate/app.o will contain all the
> required code from libzinc (and libcore), so I proceed to linker:
>
> arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T
> ./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o
> -L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m
> --gc-sections -lgcc
>
> Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto
> step didn't keep the __STACK_LIMIT (which is, along with __morestack, used
> implicitly).
>
> I have the same problem with ISRs that re defined in libzinc. For now, I
> make trampolines in the app code:
>
> #[no_mangle]
> #[inline(never)]
> #[no_split_stack]
> pub unsafe fn task_scheduler() {
>   task::task_scheduler();
> }
>
> that look bad, but I don't yet know a better way to do it.
>
> I cannot move __STACK_LIMIT or __morestack in a dedicated object file and
> pass it to linker, as those depend on libzinc which isn't reaching the
> linker explicitly.
>
>
> On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton  wrote:
>
>> In an rlib, all publicly reachable symbols will be exported from the
>> object, for example:
>>
>>
>> mod foo { pub static BAR: int = 3; }
>>
>> That symbol is not exported because BAR is not reachable from the outside
>> world.
>>
>> pub use foo::BAR;
>> mod foo { pub static BAR: int = 3; }
>>
>> This time, BAR will be an exported symbol because it is publicly
>> reachable (you could also make 'foo' public).
>>
>> Would that help your use case, or are you thinking of something more
>> complex?
>>
>> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov 
>> wrote:
>> > I have the following setup:
>> >
>> >   libzinc, compiles as rlib, provides all the stuff
>> >   support, compiles as obj, provides __morestack, memset/memcpy and
>> other
>> > required things
>> >   libapp, compiles as staticlib emitting obj, depends on libzinc, builds
>> > with lto.
>> >
>> > I link libapp.o and support.o to get the final binary.
>> >
>> > Now, to make multitasking work, I need to move __morestack into
>> libzinc, so
>> > that I can access task API from the function. The problem is that
>> publicly
>> > visible __morestack in libzinc is not visible from libapp, which
>> requires it
>> > implicitly via function prologues. Other static symbols (like
>> __STACK_LIMIT)
>> > are not available as well.
>> >
>> > Is there any way to promote the visibility of symbols from libzinc to
>> libapp
>> > in this case?
>> >
>> > --
>> > Sincerely,
>> > Vladimir "Farcaller" Pouzanov
>> > http://farcaller.net/
>> >
>> > ___
>> > Rust-dev mailing list
>> > Rust-dev@mozilla.org
>> > https://mail.mozilla.org/listinfo/rust-dev
>> >
>>
>
>
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
Right, so I have a publicly reachable symbol __STACK_LIMIT inside my
libzinc rlib:

#[no_mangle]
pub static mut __STACK_LIMIT: u32 = 0;

which is present in rlib's object file:

% arm-none-eabi-nm zinc.o|grep __STACK_LIMIT
 B __STACK_LIMIT

Now, I compile my application, which is a staticlib, emiting an obj (I
could change staticlib to binary, that doesn't really change anything at
this emit level):

rustc -Z no-landing-pads -C relocation_model=static --target
thumbv7m-linux-eabi -Ctarget-cpu=cortex-m3 --opt-level 2 -Z lto --emit obj
-L ./build -o ./build/intermediate/app.o ./apps/app_sched.rs

Which implicitly links to libzinc-de5e5c68-0.0.rlib.

Given the lto nature, ./build/intermediate/app.o will contain all the
required code from libzinc (and libcore), so I proceed to linker:

arm-none-eabi-ld -Map ./build/zinc.map -o ./build/zinc.elf -T
./src/hal/lpc17xx/layout.ld ./build/intermediate/app.o
-L/opt/gcc-arm-none-eabi-4_7-2013q3/lib/gcc/arm-none-eabi/4.7.4/armv7-m
--gc-sections -lgcc

Which fails due to "undefined reference to `__STACK_LIMIT'", as the lto
step didn't keep the __STACK_LIMIT (which is, along with __morestack, used
implicitly).

I have the same problem with ISRs that re defined in libzinc. For now, I
make trampolines in the app code:

#[no_mangle]
#[inline(never)]
#[no_split_stack]
pub unsafe fn task_scheduler() {
  task::task_scheduler();
}

that look bad, but I don't yet know a better way to do it.

I cannot move __STACK_LIMIT or __morestack in a dedicated object file and
pass it to linker, as those depend on libzinc which isn't reaching the
linker explicitly.


On Wed, Apr 30, 2014 at 5:17 PM, Alex Crichton  wrote:

> In an rlib, all publicly reachable symbols will be exported from the
> object, for example:
>
>
> mod foo { pub static BAR: int = 3; }
>
> That symbol is not exported because BAR is not reachable from the outside
> world.
>
> pub use foo::BAR;
> mod foo { pub static BAR: int = 3; }
>
> This time, BAR will be an exported symbol because it is publicly
> reachable (you could also make 'foo' public).
>
> Would that help your use case, or are you thinking of something more
> complex?
>
> On Wed, Apr 30, 2014 at 6:49 AM, Vladimir Pouzanov 
> wrote:
> > I have the following setup:
> >
> >   libzinc, compiles as rlib, provides all the stuff
> >   support, compiles as obj, provides __morestack, memset/memcpy and other
> > required things
> >   libapp, compiles as staticlib emitting obj, depends on libzinc, builds
> > with lto.
> >
> > I link libapp.o and support.o to get the final binary.
> >
> > Now, to make multitasking work, I need to move __morestack into libzinc,
> so
> > that I can access task API from the function. The problem is that
> publicly
> > visible __morestack in libzinc is not visible from libapp, which
> requires it
> > implicitly via function prologues. Other static symbols (like
> __STACK_LIMIT)
> > are not available as well.
> >
> > Is there any way to promote the visibility of symbols from libzinc to
> libapp
> > in this case?
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Symbol visibility problem

2014-04-30 Thread Vladimir Pouzanov
I have the following setup:

  libzinc, compiles as rlib, provides all the stuff
  support, compiles as obj, provides __morestack, memset/memcpy and other
required things
  libapp, compiles as staticlib emitting obj, depends on libzinc, builds
with lto.

I link libapp.o and support.o to get the final binary.

Now, to make multitasking work, I need to move __morestack into libzinc, so
that I can access task API from the function. The problem is that publicly
visible __morestack in libzinc is not visible from libapp, which requires
it implicitly via function prologues. Other static symbols (like
__STACK_LIMIT) are not available as well.

Is there any way to promote the visibility of symbols from libzinc to
libapp in this case?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-30 Thread Vladimir Pouzanov
I guess I've misread how __STACK_LIMIT works, it seems that I can change
it's value on context switch so that it keeps track of the current running
task. Works flawlessly, so I'm going to proceed with my original patch now.


On Fri, Apr 25, 2014 at 6:33 PM, Vladimir Pouzanov wrote:

> AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M
> MCUs that I'm toying with aren't usually compatible with any "full-blown"
> OS, and all the RTOSes out there have different implementations of
> multithreading and TLS, utilising the "none" OS target of gcc. The best way
> to deal with this would be to specify "arm-none-eabi" ABI for llvm, that
> would include tls behaviour amongst other things, but that sounds like a
> very complex task.
>
>
> On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton  wrote:
>
>> The prologue is run on every single function executed in a program, so
>> I believe that in the hopes of keeping it as light as possible it
>> never makes any function calls.
>>
>> I do agree though, that it's at tricky situation in that case. How
>> does TLS otherwise work for that platform?
>>
>> On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov 
>> wrote:
>> > I have a side question related to the same code.
>> >
>> > Currently __STACK_LIMIT is constant, but I would like the preamble to
>> verify
>> > stack overflow for multithreaded context, i.e. __STACK_LIMIT will
>> depend on
>> > the current running thread. Is there any reason, why it's not a
>> function?
>> > Any objections if I do some refactoring and make it a function? For a
>> simple
>> > case that could be a weak symbol that returns a constant.
>> >
>> >
>> > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton 
>> wrote:
>> >>
>> >> I agree with Corey, it's much better to send it upstream first. I'd be
>> >> more than willing to help you out with writing tests or taking a peek
>> >> at the patch if you want! I'm acrichto on IRC
>> >>
>> >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov <
>> farcal...@gmail.com>
>> >> wrote:
>> >> > The problem is that mrc is generated unless target is thumb1, but
>> >> > cortex-m3
>> >> > is thumb2 that still doesn't support mrc:
>> >> >
>> >> >
>> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
>> ,
>> >> > so an additional check to ST->TargetTriple.Data is required to verify
>> >> > it's
>> >> > not thumbv7m.
>> >> >
>> >> > Do I need to submit patch against https://github.com/rust-lang/llvmor
>> >> > send
>> >> > it to upstream?
>> >> >
>> >> >
>> >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov <
>> farcal...@gmail.com>
>> >> > wrote:
>> >> >>
>> >> >> Hm, it seems to have precautions to stop mrc from materializing on
>> >> >> Thumb1.
>> >> >> I guess I need to take a better look into what's going wrong on my
>> >> >> side.
>> >> >> I'll see what I can do with that.
>> >> >>
>> >> >>
>> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton 
>> >> >> wrote:
>> >> >>>
>> >> >>> The split stack patches for ARM were recently upstreamed, and they
>> >> >>> were modified when being upstreamed as well. Primarily the
>> location of
>> >> >>> the split stack is no longer at a magic address for thumb, but
>> rather
>> >> >>> it uses the same instruction as ARM (some thumb processors do
>> indeed
>> >> >>> have the coprocessor). More information is in the long thread
>> starting
>> >> >>> at the initial attempt to upstream [1].
>> >> >>>
>> >> >>> For now you'll have to use no_split_stack because the thumb split
>> >> >>> stack will always use a coprocessor, but I'm sure that the upstream
>> >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack
>> support
>> >> >>> (I'd also be willing to help). You can find the initial commit for
>> >> >>> support at rust-lang/llvm [2].
>> >> >>>

Re: [rust-dev] morestack prologue contains broken machine code

2014-04-25 Thread Vladimir Pouzanov
AFAIK, it's emulated in software with __tls_get_addr. Mind that Cortex-M
MCUs that I'm toying with aren't usually compatible with any "full-blown"
OS, and all the RTOSes out there have different implementations of
multithreading and TLS, utilising the "none" OS target of gcc. The best way
to deal with this would be to specify "arm-none-eabi" ABI for llvm, that
would include tls behaviour amongst other things, but that sounds like a
very complex task.


On Fri, Apr 25, 2014 at 5:20 PM, Alex Crichton  wrote:

> The prologue is run on every single function executed in a program, so
> I believe that in the hopes of keeping it as light as possible it
> never makes any function calls.
>
> I do agree though, that it's at tricky situation in that case. How
> does TLS otherwise work for that platform?
>
> On Fri, Apr 25, 2014 at 8:14 AM, Vladimir Pouzanov 
> wrote:
> > I have a side question related to the same code.
> >
> > Currently __STACK_LIMIT is constant, but I would like the preamble to
> verify
> > stack overflow for multithreaded context, i.e. __STACK_LIMIT will depend
> on
> > the current running thread. Is there any reason, why it's not a function?
> > Any objections if I do some refactoring and make it a function? For a
> simple
> > case that could be a weak symbol that returns a constant.
> >
> >
> > On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton  wrote:
> >>
> >> I agree with Corey, it's much better to send it upstream first. I'd be
> >> more than willing to help you out with writing tests or taking a peek
> >> at the patch if you want! I'm acrichto on IRC
> >>
> >> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >> wrote:
> >> > The problem is that mrc is generated unless target is thumb1, but
> >> > cortex-m3
> >> > is thumb2 that still doesn't support mrc:
> >> >
> >> >
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
> ,
> >> > so an additional check to ST->TargetTriple.Data is required to verify
> >> > it's
> >> > not thumbv7m.
> >> >
> >> > Do I need to submit patch against https://github.com/rust-lang/llvmor
> >> > send
> >> > it to upstream?
> >> >
> >> >
> >> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >> > wrote:
> >> >>
> >> >> Hm, it seems to have precautions to stop mrc from materializing on
> >> >> Thumb1.
> >> >> I guess I need to take a better look into what's going wrong on my
> >> >> side.
> >> >> I'll see what I can do with that.
> >> >>
> >> >>
> >> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton 
> >> >> wrote:
> >> >>>
> >> >>> The split stack patches for ARM were recently upstreamed, and they
> >> >>> were modified when being upstreamed as well. Primarily the location
> of
> >> >>> the split stack is no longer at a magic address for thumb, but
> rather
> >> >>> it uses the same instruction as ARM (some thumb processors do indeed
> >> >>> have the coprocessor). More information is in the long thread
> starting
> >> >>> at the initial attempt to upstream [1].
> >> >>>
> >> >>> For now you'll have to use no_split_stack because the thumb split
> >> >>> stack will always use a coprocessor, but I'm sure that the upstream
> >> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack
> support
> >> >>> (I'd also be willing to help). You can find the initial commit for
> >> >>> support at rust-lang/llvm [2].
> >> >>>
> >> >>> [1] -
> >> >>>
> >> >>>
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
> >> >>> [2] - https://github.com/rust-lang/llvm/pull/4
> >> >>>
> >> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov
> >> >>> 
> >> >>> wrote:
> >> >>> > Starting recently (no more than two weeks), rustc is generating a
> >> >>> > broken
> >> >>> > prologue for arm. Here's the sample assembly:
> >> >>> >0x0f44 <+0>: 

Re: [rust-dev] morestack prologue contains broken machine code

2014-04-25 Thread Vladimir Pouzanov
I have a side question related to the same code.

Currently __STACK_LIMIT is constant, but I would like the preamble to
verify stack overflow for multithreaded context, i.e. __STACK_LIMIT will
depend on the current running thread. Is there any reason, why it's not a
function? Any objections if I do some refactoring and make it a function?
For a simple case that could be a weak symbol that returns a constant.


On Tue, Apr 22, 2014 at 9:00 AM, Alex Crichton  wrote:

> I agree with Corey, it's much better to send it upstream first. I'd be
> more than willing to help you out with writing tests or taking a peek
> at the patch if you want! I'm acrichto on IRC
>
> On Tue, Apr 22, 2014 at 12:43 AM, Vladimir Pouzanov 
> wrote:
> > The problem is that mrc is generated unless target is thumb1, but
> cortex-m3
> > is thumb2 that still doesn't support mrc:
> >
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html
> ,
> > so an additional check to ST->TargetTriple.Data is required to verify
> it's
> > not thumbv7m.
> >
> > Do I need to submit patch against https://github.com/rust-lang/llvm or
> send
> > it to upstream?
> >
> >
> > On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov 
> > wrote:
> >>
> >> Hm, it seems to have precautions to stop mrc from materializing on
> Thumb1.
> >> I guess I need to take a better look into what's going wrong on my side.
> >> I'll see what I can do with that.
> >>
> >>
> >> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton 
> wrote:
> >>>
> >>> The split stack patches for ARM were recently upstreamed, and they
> >>> were modified when being upstreamed as well. Primarily the location of
> >>> the split stack is no longer at a magic address for thumb, but rather
> >>> it uses the same instruction as ARM (some thumb processors do indeed
> >>> have the coprocessor). More information is in the long thread starting
> >>> at the initial attempt to upstream [1].
> >>>
> >>> For now you'll have to use no_split_stack because the thumb split
> >>> stack will always use a coprocessor, but I'm sure that the upstream
> >>> LLVM devs would be quite welcoming to tweaks to the slit-stack support
> >>> (I'd also be willing to help). You can find the initial commit for
> >>> support at rust-lang/llvm [2].
> >>>
> >>> [1] -
> >>>
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
> >>> [2] - https://github.com/rust-lang/llvm/pull/4
> >>>
> >>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >>> wrote:
> >>> > Starting recently (no more than two weeks), rustc is generating a
> >>> > broken
> >>> > prologue for arm. Here's the sample assembly:
> >>> >0x0f44 <+0>: push {r4, r5}
> >>> > => 0x0f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3}
> >>> >0x0f4a <+6>: mov r5, sp
> >>> >0x0f4c <+8>: b.n 0xa78 
> >>> >0x0f4e <+10>: ands r4, r0
> >>> >0x0f50 <+12>: cmp r4, r5
> >>> >0x0f52 <+14>: bcc.n 0xf66
> >>> >
> >>> >
> <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34>
> >>> >0x0f54 <+16>: movs r4, #16
> >>> >0x0f56 <+18>: movs r5, #0
> >>> >0x0f58 <+20>: push {lr}
> >>> >0x0f5a <+22>: bl 0x19d8 <__morestack>
> >>> >0x0f5e <+26>: ldr.w lr, [sp], #4
> >>> >0x0f62 <+30>: pop {r4, r5}
> >>> >0x0f64 <+32>: bx lr
> >>> >
> >>> > The problem is at 0x0f46, where code tries to read from
> coprocessor
> >>> > 15
> >>> > register 13, which is "process id register". Well, coprocessor 15
> >>> > (actually,
> >>> > all of the coprocessors) are missing from my target
> thumbv7m-linux-eabi
> >>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be
> >>> > redundant
> >>> > anyway), so I'm getting hardfaults in every function that rust
> doesn't
> >>> > inline.
> >>> >
> >>> > Any ideas on what might be going wrong? I assume that this is
> actually
> >>> > llvm's fault, as llvm should not materialize machine code which is
> not
> >>> > available for target anyway.
> >>> >
> >>> > Wrapping everything in #[no_split_stack] is a temporary workaround
> and
> >>> > surely not a long-term strategy.
> >>> >
> >>> > --
> >>> > Sincerely,
> >>> > Vladimir "Farcaller" Pouzanov
> >>> > http://farcaller.net/
> >>> >
> >>> > ___
> >>> > Rust-dev mailing list
> >>> > Rust-dev@mozilla.org
> >>> > https://mail.mozilla.org/listinfo/rust-dev
> >>> >
> >>
> >>
> >>
> >>
> >> --
> >> Sincerely,
> >> Vladimir "Farcaller" Pouzanov
> >> http://farcaller.net/
> >
> >
> >
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-25 Thread Vladimir Pouzanov
A few ideas:

 * make a static P that manages *T storage inside it. *T could be
statically pointed to heap block in ram, P will wrap the API to make it
less verbose.
 * use Cell to make internals of immutable mutable back again. This would
not work with statics, obviously, as they will land in .rodata, but we
have #[link_section] to deal with that.
 * same as above, but use extern with further linker script placement (same
way as I deal with ioregs in zinc).


On Thu, Apr 24, 2014 at 11:37 PM, Ben Gamari  wrote:

> Ben Gamari  writes:
>
> > Vladimir Pouzanov  writes:
> >
> ...
>
> >> My current idea is to make dedicated pools that could hold a
> compile-time
> >> configurable number of objects of same size, e.g. an IncomingPacketPool
> >> that can hold up to 3 frames where one frame is 128 bytes long. This
> way no
> >> other running process can interfere with code that processes incoming
> >> packets and that code can offload incoming packets into the pool for
> later
> >> processing, but up to three, and it will act in user-defined fashion
> (drop
> >> packets) if the pool is full. The implementation of that would be quite
> >> simple, and I think that it might be possible to extend ~T ownership for
> >> something like that.
> >>
> > I tried playing around (warning: code written by new Rust-er, expect
> > eye damage, feedback welcome) with a simple buffer pool implementation
> > this morning; unfortunately I found that Rust's restrictions on function
> > application in constant expressions makes static allocation quite
> > difficult (impossible?),
> >
> Tonight I played around with using the macro system to work around the
> static initializer limitation. The result[1] isn't terrible, but
> it didn't take long for me to run into a mutability issue. In short, I
> was inadvertently declaring my static pool as immutable, causing it to
> end up in the data.rel.ro section, resulting in a segfault when I attempt
> to increment the reference count (held in an `Unsafe`).
>
> I thought the obvious way around this would be to declare the pool as
> `static mut` but
> this unfortunately makes things quite verbose as one must declare each
> point of usage as `unsafe`. Moreover, for reasons I don't quite yet
> understand it seems that some data is still being placed in a read-only
> section and therefore the crash reappears. Regardless, it seems that
> mutable statics might be another sticking point in embedded contexts
> where static allocation is often desirable.
>
> Anyone have any clever ideas for dealing with this?
>
> Cheers,
>
> - Ben
>
>
> [1] https://gist.github.com/bgamari/033379d82f179eac8688
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-24 Thread Vladimir Pouzanov
On Thu, Apr 24, 2014 at 9:01 AM, Ben Gamari  wrote:

> Unfortunately this replaces the ugly possibility of unpredictable
> crashes with the slightly less ugly possiblity of unpredictable
> deadlocks if we run out of stack in the middle of execution. Perhaps
> threads could be annotated with their maximum expected stack size,
> allowing stack chunks to be allocated at spawn-time.
>

It wouldn't be allowed to grow, it's exactly that — maximum expected stack
size, task either fits in there or dies.


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-23 Thread Vladimir Pouzanov
There is a number of options on the memory side of things. I feel that
stack usage could be estimated a bit more simply with rust and it's
__morestack support, so that it would be possible to run a few threads with
preemptive scheduling (__morestack also guarantees that no memory
corruption would occur due to stack overflow).

I'm totally against "unmanaged" heap support and ~T on embedded, that just
doesn't work. It's a very big burden to support that reasonably in existing
C/C++ RTOSes out there, so I don't want to spend lots of time trying to
solve the same problems. Still, heap is really useful in some cases (as
I've figured out while working on 802.15.4 stack for zinc).

My current idea is to make dedicated pools that could hold a compile-time
configurable number of objects of same size, e.g. an IncomingPacketPool
that can hold up to 3 frames where one frame is 128 bytes long. This way no
other running process can interfere with code that processes incoming
packets and that code can offload incoming packets into the pool for later
processing, but up to three, and it will act in user-defined fashion (drop
packets) if the pool is full. The implementation of that would be quite
simple, and I think that it might be possible to extend ~T ownership for
something like that.


On Wed, Apr 23, 2014 at 3:47 PM, Ben Gamari  wrote:

> Vladimir Pouzanov  writes:
>
> > This is the project I've been tinkering with for a good number of
> > weekends zinc, the bare metal stack for rust is available at
> > https://github.com/hackndev/zinc.
> >
> > I've just finished a major refactoring work for LPC1768 code, so
> > STM32F4 is kind of broken yet, and LPC1114 is totally dropped, but
> > I'll fix that soon.
> >
> > The current code supports GPIO operations, UART and SSP in SPI mode
> > for NXP LPC1768, also featuring a driver for
> > http://mbed.org/cookbook/mbed-application-board TFT LCD and for
> > ILI9341-based TFT LCDs commonly found on ebay.
> >
> > My plan is to fix support for STM32F4, bring it to the level of NXP
> > part and try to expand this to a small RTOS, which would be a nice
> > demo of rust capabilities for embedded development.
> >
> > The code is licensed under Apache-2.0.
> >
> > There's no readme yet, but you can see the demo applications written
> > with zinc here: https://github.com/hackndev/zinc/tree/master/apps.
> >
> Thanks for the release! I've been looking forward to seeing this ever
> since your Reddit post a few weeks back as I too have been recently
> thinking about how Rust might be used in an embedded environment.
>
> Lately I've been contributing to the mchck[1] project, its associated
> library, and a project I've built on top of it[2]. One of the things
> that I feel the mchck library gets right is the ubiquitous use of
> asynchronous completion notification (e.g. [3]) instead of polling. In
> my experience asynchronous code both maps onto hardware more naturally
> and produces more composable user code. Unfortunately, C makes
> continuation passing very painful due to the broken up flow of control
> that results from the sea of callbacks and the boilerplate (e.g. passing
> and casting of `void*` pointers to structs of intermediate state)
> necessary for propagation of state between callbacks.
>
> As far as I can tell, there are two paths by which Rust might improve
> this situation. The most straightforward approach would be to implement
> continuation passing directly by passing around continuation
> `procs`. While this approach reduces the amount of boilerplate due to
> state propagation, it does not really resolve the broken flow of control
> due to explicit continuations.
>
> Another approach which addresses this latter issue is to use Rust's
> native tasks, allowing requests to peripherals to be treated as
> blocking. While this seems like this could be very convenient, I am a bit
> concerned that the memory footprint of multiple stacks and associated
> bookkeeping data structures might be asking too much of the typical
> MCU (the devices I work with typically have 16kByte of SRAM).
>
> This memory footprint issue is especially concerning due to Rust's[4]
> heavy dependence on stack allocation. I am very much accustomed to
> avoiding dynamic allocation at all costs on embedded platforms; I
> appreciate knowing at compile time whether my program will fit on my
> device (up to stack allocations, which in my C code are intentionally
> minimal). With the uncertainty of dynamic allocation against the stack
> and dynamic task creation, it seems one literally has no idea whether a
> program will fit without either static analysis, simulation, or trial on
&g

Re: [rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-23 Thread Vladimir Pouzanov
Luckily enough, I had the concept for zinc even before I started coding in
rust :-) And yes, there are lots of different oxides in rust world.


On Wed, Apr 23, 2014 at 3:58 AM, Thad Guidry  wrote:

> Actually...I do not. :)
>
>
> On Tue, Apr 22, 2014 at 9:05 PM, Chris Morgan  wrote:
>
>> On Wed, Apr 23, 2014 at 10:35 AM, Thad Guidry 
>> wrote:
>> > I would have named it ... "oxide" instead of zinc ;-) ... rust = iron
>> oxide
>> Do you know how many projects written in Rust have already been named
>> “oxide”?
>>
>
>
>
> --
> -Thad
> +ThadGuidry 
> Thad on LinkedIn 
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A small announcement for zinc, the bare metal rust stack

2014-04-22 Thread Vladimir Pouzanov
This is the project I've been tinkering with for a good number of weekends
— zinc, the bare metal stack for rust is available at
https://github.com/hackndev/zinc.

I've just finished a major refactoring work for LPC1768 code, so STM32F4 is
kind of broken yet, and LPC1114 is totally dropped, but I'll fix that soon.

The current code supports GPIO operations, UART and SSP in SPI mode for NXP
LPC1768, also featuring a driver for
http://mbed.org/cookbook/mbed-application-board TFT LCD and for
ILI9341-based TFT LCDs commonly found on ebay.

My plan is to fix support for STM32F4, bring it to the level of NXP part
and try to expand this to a small RTOS, which would be a nice demo of rust
capabilities for embedded development.

The code is licensed under Apache-2.0.

There's no readme yet, but you can see the demo applications written with
zinc here: https://github.com/hackndev/zinc/tree/master/apps.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-22 Thread Vladimir Pouzanov
The problem is that mrc is generated unless target is thumb1, but cortex-m3
is thumb2 that still doesn't support mrc:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka398.html,
so an additional check to ST->TargetTriple.Data is required to verify it's
not thumbv7m.

Do I need to submit patch against https://github.com/rust-lang/llvm or send
it to upstream?


On Mon, Apr 21, 2014 at 6:34 PM, Vladimir Pouzanov wrote:

> Hm, it seems to have precautions to stop mrc from materializing on Thumb1.
> I guess I need to take a better look into what's going wrong on my side.
> I'll see what I can do with that.
>
>
> On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton  wrote:
>
>> The split stack patches for ARM were recently upstreamed, and they
>> were modified when being upstreamed as well. Primarily the location of
>> the split stack is no longer at a magic address for thumb, but rather
>> it uses the same instruction as ARM (some thumb processors do indeed
>> have the coprocessor). More information is in the long thread starting
>> at the initial attempt to upstream [1].
>>
>> For now you'll have to use no_split_stack because the thumb split
>> stack will always use a coprocessor, but I'm sure that the upstream
>> LLVM devs would be quite welcoming to tweaks to the slit-stack support
>> (I'd also be willing to help). You can find the initial commit for
>> support at rust-lang/llvm [2].
>>
>> [1] -
>> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
>> [2] - https://github.com/rust-lang/llvm/pull/4
>>
>> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov 
>> wrote:
>> > Starting recently (no more than two weeks), rustc is generating a broken
>> > prologue for arm. Here's the sample assembly:
>> >0x0f44 <+0>: push {r4, r5}
>> > => 0x0f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3}
>> >0x0f4a <+6>: mov r5, sp
>> >0x0f4c <+8>: b.n 0xa78 
>> >0x0f4e <+10>: ands r4, r0
>> >0x0f50 <+12>: cmp r4, r5
>> >0x0f52 <+14>: bcc.n 0xf66
>> >
>> <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34>
>> >0x0f54 <+16>: movs r4, #16
>> >0x0f56 <+18>: movs r5, #0
>> >0x0f58 <+20>: push {lr}
>> >0x0f5a <+22>: bl 0x19d8 <__morestack>
>> >0x0f5e <+26>: ldr.w lr, [sp], #4
>> >0x0f62 <+30>: pop {r4, r5}
>> >0x0f64 <+32>: bx lr
>> >
>> > The problem is at 0x0f46, where code tries to read from coprocessor
>> 15
>> > register 13, which is "process id register". Well, coprocessor 15
>> (actually,
>> > all of the coprocessors) are missing from my target thumbv7m-linux-eabi
>> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant
>> > anyway), so I'm getting hardfaults in every function that rust doesn't
>> > inline.
>> >
>> > Any ideas on what might be going wrong? I assume that this is actually
>> > llvm's fault, as llvm should not materialize machine code which is not
>> > available for target anyway.
>> >
>> > Wrapping everything in #[no_split_stack] is a temporary workaround and
>> > surely not a long-term strategy.
>> >
>> > --
>> > Sincerely,
>> > Vladimir "Farcaller" Pouzanov
>> > http://farcaller.net/
>> >
>> > ___
>> > Rust-dev mailing list
>> > Rust-dev@mozilla.org
>> > https://mail.mozilla.org/listinfo/rust-dev
>> >
>>
>
>
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] morestack prologue contains broken machine code

2014-04-21 Thread Vladimir Pouzanov
Hm, it seems to have precautions to stop mrc from materializing on Thumb1.
I guess I need to take a better look into what's going wrong on my side.
I'll see what I can do with that.


On Mon, Apr 21, 2014 at 5:23 PM, Alex Crichton  wrote:

> The split stack patches for ARM were recently upstreamed, and they
> were modified when being upstreamed as well. Primarily the location of
> the split stack is no longer at a magic address for thumb, but rather
> it uses the same instruction as ARM (some thumb processors do indeed
> have the coprocessor). More information is in the long thread starting
> at the initial attempt to upstream [1].
>
> For now you'll have to use no_split_stack because the thumb split
> stack will always use a coprocessor, but I'm sure that the upstream
> LLVM devs would be quite welcoming to tweaks to the slit-stack support
> (I'd also be willing to help). You can find the initial commit for
> support at rust-lang/llvm [2].
>
> [1] -
> http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140224/205968.html
> [2] - https://github.com/rust-lang/llvm/pull/4
>
> On Mon, Apr 21, 2014 at 6:50 AM, Vladimir Pouzanov 
> wrote:
> > Starting recently (no more than two weeks), rustc is generating a broken
> > prologue for arm. Here's the sample assembly:
> >0x0f44 <+0>: push {r4, r5}
> > => 0x0f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3}
> >0x0f4a <+6>: mov r5, sp
> >0x0f4c <+8>: b.n 0xa78 
> >0x0f4e <+10>: ands r4, r0
> >0x0f50 <+12>: cmp r4, r5
> >0x0f52 <+14>: bcc.n 0xf66
> >
> <_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34>
> >0x0f54 <+16>: movs r4, #16
> >0x0f56 <+18>: movs r5, #0
> >0x0f58 <+20>: push {lr}
> >0x0f5a <+22>: bl 0x19d8 <__morestack>
> >0x0f5e <+26>: ldr.w lr, [sp], #4
> >0x0f62 <+30>: pop {r4, r5}
> >0x0f64 <+32>: bx lr
> >
> > The problem is at 0x0f46, where code tries to read from coprocessor
> 15
> > register 13, which is "process id register". Well, coprocessor 15
> (actually,
> > all of the coprocessors) are missing from my target thumbv7m-linux-eabi
> > (with added flavour of -Ctarget-cpu=cortex-m3, which should be redundant
> > anyway), so I'm getting hardfaults in every function that rust doesn't
> > inline.
> >
> > Any ideas on what might be going wrong? I assume that this is actually
> > llvm's fault, as llvm should not materialize machine code which is not
> > available for target anyway.
> >
> > Wrapping everything in #[no_split_stack] is a temporary workaround and
> > surely not a long-term strategy.
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] morestack prologue contains broken machine code

2014-04-21 Thread Vladimir Pouzanov
Starting recently (no more than two weeks), rustc is generating a broken
prologue for arm. Here's the sample assembly:
   0x0f44 <+0>: push {r4, r5}
=> 0x0f46 <+2>: mrc 15, 0, r4, cr13, cr0, {3}
   0x0f4a <+6>: mov r5, sp
   0x0f4c <+8>: b.n 0xa78 
   0x0f4e <+10>: ands r4, r0
   0x0f50 <+12>: cmp r4, r5
   0x0f52 <+14>: bcc.n 0xf66
<_ZN7drivers3lcd6c1233244C12332$LT$$x27a$C$$x20S$C$$x20T$GT$.lcd..LCD5flush20h76589116290686712394v0.0E+34>
   0x0f54 <+16>: movs r4, #16
   0x0f56 <+18>: movs r5, #0
   0x0f58 <+20>: push {lr}
   0x0f5a <+22>: bl 0x19d8 <__morestack>
   0x0f5e <+26>: ldr.w lr, [sp], #4
   0x0f62 <+30>: pop {r4, r5}
   0x0f64 <+32>: bx lr

The problem is at 0x0f46, where code tries to read from coprocessor 15
register 13, which is "process id register". Well, coprocessor 15
(actually, all of the coprocessors) are missing from my
target thumbv7m-linux-eabi (with added flavour of -Ctarget-cpu=cortex-m3,
which should be redundant anyway), so I'm getting hardfaults in every
function that rust doesn't inline.

Any ideas on what might be going wrong? I assume that this is actually
llvm's fault, as llvm should not materialize machine code which is not
available for target anyway.

Wrapping everything in #[no_split_stack] is a temporary workaround and
surely not a long-term strategy.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] LLVM doesn't inline my static, any good reason for that?

2014-04-20 Thread Vladimir Pouzanov
Apparently I had a problem of double pointer. The solution was to use

static Tinst : &'static T = 1000;

though I have modified the code now so that T works as well.


On Sun, Apr 20, 2014 at 2:04 PM, György Andrasek  wrote:

> On Sun, Apr 20, 2014 at 10:46 AM, Vladimir Pouzanov 
> wrote:
> > The results in the following IR:
> >
> > @Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*)
> >
> > The problem is that llvm never inlines the constant (even with
> > #[address_insignificant]), so instead of making the binary smaller as
> llvm
> > can optimize integer addresses better (as it knows them) it makes the
> binary
> > bigger, as it takes 4 bytes to store address value in .rodata, and two
> > instructions to fetch it.
>
> Does it show up in the asm after optimizations? After LTO?
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] LLVM doesn't inline my static, any good reason for that?

2014-04-20 Thread Vladimir Pouzanov
I'm working on a proof-of-concept implementation for
https://github.com/rust-lang/rfcs/pull/44 [Linker placement attribute], and
I actually got code that is working, but the outcome is worse than I
expected.

Consider the following snippet:

#[unsafe_override_address]
static Tinst : T = 1000;

What it is expected to do is to create a '1000 as *T' with the semantics of
T (the reasons for that are in RFC).

My patch actually works as expected in this regard, I evaluate the expr as
uint, and store a LLVMConstIntToPtr made from that uint
in ccx.const_values. The results in the following IR:

@Tinst = internal constant %struct.T* inttoptr (i32 1000 to %struct.T*)

The problem is that llvm never inlines the constant (even
with #[address_insignificant]), so instead of making the binary smaller as
llvm can optimize integer addresses better (as it knows them) it makes the
binary bigger, as it takes 4 bytes to store address value in .rodata, and
two instructions to fetch it.

Any ideas on what I could be missing?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Convincing compiler that *T is safe

2014-04-14 Thread Vladimir Pouzanov
Well, the &Dev as a pointer would be immutable in terms of that you can't
change its address, and all access to fields is done via getter/setter
methods using volatiles.

It seems that I cannot use transmute in a context of static though and I
can't trade runtime size over better syntax.


On Mon, Apr 14, 2014 at 10:19 AM, Huon Wilson  wrote:

>  On 14/04/14 06:12, Vladimir Pouzanov wrote:
>
> I have a number of I/O mapped registers that look like:
>
>  struct Dev {
>   .. // u32 fields
> }
>
>  pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev;
>
>  with macro-generated getters and setters:
>
>  pub fn $getter_name(&self) -> u32 {
>   unsafe { volatile_load(&(self.$reg)) }
> }
>
>  unfortunately, calling a getter is calling a method on *Reg, which is
> unsafe and looks like:
>
>  unsafe { (*Dev0).SOME_REG() };
>
>  is there any way to simplify the syntax, hopefully to simple
> Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting it
> to &Dev (that doesn't seem to be possible though), as the getter/setter
> methods are always safe in this scenario.
>
>  --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>
>
> ___
> Rust-dev mailing 
> listRust-dev@mozilla.orghttps://mail.mozilla.org/listinfo/rust-dev
>
>
>
> The compiler cannot verify that these method calls are safe, so they
> `unsafe`'s are asserting "trust me compiler, I know more than you".
>
>
> You could write a macro like `get!(Dev0, SOME_REG)` that expanded to the
> `unsafe { (*Dev0).SOME_REG() }` invocation.
>
>
> But... I don't understand why transmuting to &Dev wouldn't be possible.
> I'd strongly recommend the weaker version `unsafe { &*Dev0 }`, to go from
> *mut Dev to &Dev0. However, this likely breaks the guarantees of &, since
> the data to which they point is supposed to be immutable, but being I/O
> mapped registers it would imply that external events can change the values.
> (I guess this is where Flavio's suggestion of storing a *Unsafe comes
> into play, but this still leaves you dealing with an *mut pointer to get at
> the data, at the end of the day.)
>
>
> Huon
>
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Convincing compiler that *T is safe

2014-04-14 Thread Vladimir Pouzanov
Looks nice, but in this case pub static Dev0: Dev isn't getting optimised
away, adding bytes to the binary; that's not an acceptable tradeoff. Any
other ideas?


On Sun, Apr 13, 2014 at 9:22 PM, György Andrasek  wrote:

> You could make a container struct:
>
> struct Dev {
> ptr: *mut InternalDev
> }
>
> and then impl your methods on that.
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Convincing compiler that *T is safe

2014-04-13 Thread Vladimir Pouzanov
I have a number of I/O mapped registers that look like:

struct Dev {
  .. // u32 fields
}

pub static Dev0 : *mut Dev = 0xsomeaddr as *mut Dev;

with macro-generated getters and setters:

pub fn $getter_name(&self) -> u32 {
  unsafe { volatile_load(&(self.$reg)) }
}

unfortunately, calling a getter is calling a method on *Reg, which is
unsafe and looks like:

unsafe { (*Dev0).SOME_REG() };

is there any way to simplify the syntax, hopefully to simple
Dev0.SOME_REG()? I'm ok with any "unsafe" tricks including transmuting it
to &Dev (that doesn't seem to be possible though), as the getter/setter
methods are always safe in this scenario.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
Yes, in the end I decided to implement .data section copy over from flash
to ram to get vtables :-)


On Tue, Apr 8, 2014 at 7:34 PM, Corey Richardson  wrote:

> `&'static SPI` is going to be a trait object (with dynamic dispatch).
> The error it's giving is that `&SPI` (the trait object) doesn't
> implement `SPI` (the trait). You would have to explicitly implement
> `SPI` for `&SPI`. I'm not really sure  how to solve this without using
> trait objects; you seem to want an inherently dynamically-dispatched
> system.
>
> On Tue, Apr 8, 2014 at 2:08 PM, Vladimir Pouzanov 
> wrote:
> > That actually worked much better than I expected inlining everything and
> > getting rid of vtables (I don't have support for .data section at the
> moment
> > :-) ).
> >
> > I can't say the syntax is very clear to me, but I can get used to it.
> Still,
> > one more question remains. I have a "debug output" concept, which means
> that
> > debug::d("str") gets delivered to either LCD or UART, whatever is
> configured
> > at runtime. I do it via static mut:
> >
> > pub trait Debugger {
> >   fn debugs(&mut self, s: &str);
> > }
> >
> > pub static mut debug_output: *mut c12332::C12332<'static, &'static
> spi::SPI>
> > = unsafe { init() };
> >
> > pub fn d(s: &str) {
> >   let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; //
> failed
> > to find an implementation of trait hal::spi::SPI for &'static
> > hal::spi::SPI:'static
> >   debugger.debugs(s);
> > }
> >
> > pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) {
> >   unsafe { debug_output = lcd; };
> > }
> >
> > I don't really support UART now, but I'd still like to access my LCD via
> a
> > globally known static getter. How can I re-write that with typed struct?
> >
> >
> > On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson 
> wrote:
> >>
> >> You don't use bounds in the struct, you put them in the impl. So you
> >> would instead say
> >>
> >>
> >> struct LCD {
> >>   spi: S,
> >>   ...
> >> }
> >>
> >>
> >> and then:
> >>
> >> impl LCD {
> >> ...
> >> }
> >>
> >> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov 
> >> wrote:
> >> > I might have found an unsupported case.
> >> >
> >> > Consider the following:
> >> >
> >> > trait SPI { ... }
> >> >
> >> > struct McuSPI;
> >> > impl SPI for McuSPI { ... }
> >> >
> >> > struct LCD {
> >> >   spi: &SPI,
> >> >   ...
> >> > }
> >> >
> >> > This code results in a dynamic dispatch to SPI, as "trait bounds are
> not
> >> > allowed in structure definitions". Is it in any way possible to use
> >> > static
> >> > dispatch from LCD to SPI given the exact implementations are known at
> >> > compile time?
> >> >
> >> >
> >> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles 
> wrote:
> >> >>
> >> >> And just in case there is a confusion (as I have noticed others to
> >> >> have), it might help to see a specific example comparing static
> >> >> dispatch with dynamic.
> >> >>
> >> >> // This is a single function for all types implementing the LCD
> Trait.
> >> >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of
> >> >> the object being passed in
> >> >> x.line(); // dynamic dispatch
> >> >> }
> >> >>
> >> >> // Like C++ templates, this generates a function for each type T that
> >> >> implements LCD.
> >> >> fn foo(x : &T) { // x's type is &T rather than &LCD
> >> >> x.line(); // static dispatch based on type T known at
> >> >> compile-time
> >> >> }
> >> >>
> >> >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay 
> >> >> wrote:
> >> >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
> >> >> >> If I get it right, calls to traits are resolved in runtime (so,
> >> >> >> traits
> >> >> >> are kind of similar to C++ virtual methods).
> >> &

Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
That actually worked much better than I expected inlining everything and
getting rid of vtables (I don't have support for .data section at the
moment :-) ).

I can't say the syntax is very clear to me, but I can get used to it.
Still, one more question remains. I have a "debug output" concept, which
means that debug::d("str") gets delivered to either LCD or UART, whatever
is configured at runtime. I do it via static mut:

pub trait Debugger {
  fn debugs(&mut self, s: &str);
}

pub static mut debug_output: *mut c12332::C12332<'static, &'static
spi::SPI> = unsafe { init() };

pub fn d(s: &str) {
  let debugger = unsafe { &mut (*debug_output) as &mut Debugger }; //
failed to find an implementation of trait hal::spi::SPI for &'static
hal::spi::SPI:'static
  debugger.debugs(s);
}

pub fn set_debugger(lcd: *mut c12332::C12332<&spi::SPI>) {
  unsafe { debug_output = lcd; };
}

I don't really support UART now, but I'd still like to access my LCD via a
globally known static getter. How can I re-write that with typed struct?


On Tue, Apr 8, 2014 at 6:26 PM, Corey Richardson  wrote:

> You don't use bounds in the struct, you put them in the impl. So you
> would instead say
>
>
> struct LCD {
>   spi: S,
>   ...
> }
>
>
> and then:
>
> impl LCD {
> ...
> }
>
> On Tue, Apr 8, 2014 at 1:23 PM, Vladimir Pouzanov 
> wrote:
> > I might have found an unsupported case.
> >
> > Consider the following:
> >
> > trait SPI { ... }
> >
> > struct McuSPI;
> > impl SPI for McuSPI { ... }
> >
> > struct LCD {
> >   spi: &SPI,
> >   ...
> > }
> >
> > This code results in a dynamic dispatch to SPI, as "trait bounds are not
> > allowed in structure definitions". Is it in any way possible to use
> static
> > dispatch from LCD to SPI given the exact implementations are known at
> > compile time?
> >
> >
> > On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles  wrote:
> >>
> >> And just in case there is a confusion (as I have noticed others to
> >> have), it might help to see a specific example comparing static
> >> dispatch with dynamic.
> >>
> >> // This is a single function for all types implementing the LCD Trait.
> >> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of
> >> the object being passed in
> >> x.line(); // dynamic dispatch
> >> }
> >>
> >> // Like C++ templates, this generates a function for each type T that
> >> implements LCD.
> >> fn foo(x : &T) { // x's type is &T rather than &LCD
> >> x.line(); // static dispatch based on type T known at
> compile-time
> >> }
> >>
> >> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay 
> >> wrote:
> >> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
> >> >> If I get it right, calls to traits are resolved in runtime (so,
> traits
> >> >> are kind of similar to C++ virtual methods).
> >> >
> >> > All method calls on regular types are resolved via static dispatch,
> >> > whether or not they come from a trait. For example, consider a generic
> >> > function like the following:
> >> >
> >> > fn min(a: T, b: T) -> T {
> >> > if a < b { a } else { b }
> >> > }
> >> >
> >> > This function performs a *static* call of the `lt` method defined on
> the
> >> > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded
> >> > at compile-time just as C++ templates are.
> >> >
> >> > Rust also allows using traits as boxed objects, but this is an
> entirely
> >> > transparent choice. They're almost always used for static dispatch via
> >> > trait bounds on generics, or simply outside of generics.
> >> >
> >> >> What I'm proposing here is a compile-time approach.
> >> >>
> >> >> Let's say we have the following trait:
> >> >>
> >> >> pub trait LCD {
> >> >>   fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color:
> >> >> u8);
> >> >>   fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
> >> >>   fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32,
> >> >> color: u8);
> >> >>   fn putc(&mut self, value: char);
> >> >>   fn puts(&mut self,

Re: [rust-dev] Porting some nesC features to rust?

2014-04-08 Thread Vladimir Pouzanov
I might have found an unsupported case.

Consider the following:

trait SPI { ... }

struct McuSPI;
impl SPI for McuSPI { ... }

struct LCD {
  spi: &SPI,
  ...
}

This code results in a dynamic dispatch to SPI, as "trait bounds are not
allowed in structure definitions". Is it in any way possible to use static
dispatch from LCD to SPI given the exact implementations are known at
compile time?


On Thu, Apr 3, 2014 at 2:46 AM, Ashish Myles  wrote:

> And just in case there is a confusion (as I have noticed others to
> have), it might help to see a specific example comparing static
> dispatch with dynamic.
>
> // This is a single function for all types implementing the LCD Trait.
> fn foo(x : &LCD) { // x's type is &LCD rather than the actual type of
> the object being passed in
> x.line(); // dynamic dispatch
> }
>
> // Like C++ templates, this generates a function for each type T that
> implements LCD.
> fn foo(x : &T) { // x's type is &T rather than &LCD
> x.line(); // static dispatch based on type T known at compile-time
> }
>
> On Wed, Apr 2, 2014 at 8:32 AM, Daniel Micay 
> wrote:
> > On 02/04/14 06:25 AM, Vladimir Pouzanov wrote:
> >> If I get it right, calls to traits are resolved in runtime (so, traits
> >> are kind of similar to C++ virtual methods).
> >
> > All method calls on regular types are resolved via static dispatch,
> > whether or not they come from a trait. For example, consider a generic
> > function like the following:
> >
> > fn min(a: T, b: T) -> T {
> > if a < b { a } else { b }
> > }
> >
> > This function performs a *static* call of the `lt` method defined on the
> > `Ord` trait that `TotalOrd` inherits from. Generics are fully expanded
> > at compile-time just as C++ templates are.
> >
> > Rust also allows using traits as boxed objects, but this is an entirely
> > transparent choice. They're almost always used for static dispatch via
> > trait bounds on generics, or simply outside of generics.
> >
> >> What I'm proposing here is a compile-time approach.
> >>
> >> Let's say we have the following trait:
> >>
> >> pub trait LCD {
> >>   fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8);
> >>   fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
> >>   fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32,
> >> color: u8);
> >>   fn putc(&mut self, value: char);
> >>   fn puts(&mut self, s: &str);
> >>
> >>   fn flush(&self);
> >>   fn clear(&mut self);
> >> }
> >>
> >> which defined a LED screen. There are two structs implementing it:
> >> C12832 and ILI9341 (two different lcd controllers).
> >>
> >> So I want my app to print hello world on lcd, I write the following
> code:
> >>
> >>   let mut lcd = lcd_c12832::C12832::new(spi);
> >>   let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD;
> >>   l.puts("hello, world");
> >>
> >> Which results in a runtime dispatch, a slower and bigger code than the
> >> one I'd have without a trait.
> >
> > You can call methods defined on a trait without boxing the object as a
> > trait object. The ability to perform dynamic dispatch via a trait object
> > is totally optional. The methods can also be called directly, including
> > inside a generic function by specifying the trait as a type parameter
> > bound. You can simply call the `puts` method directly on the `lcd`
> > object without a cast.
> >
> >> A second problem is there is no easy way to write unified code that
> >> supports both the lcds based on passed in --cfg, as I can't
> >> apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of
> >> problematic to return a &LCD out from it given that there is no heap and
> >> no analog of placement new from C++.
> >
> > Rust supports generic functions, and you can write code supporting both
> > types by making it generic. The choice between static dispatch and
> > dynamic dispatch is entirely up to you in the current system.
> >
> >> Proposed binding concept solves those two problems:
> >>
> >> #[cfg(lcd_c12832)]
> >> let Binding: binding {
> >>   let lcd: &lcd_c12832::C12832;
> >>   let main: &Main;
> >>
> >>   bind main.lcd = lcd;
> >> }
> >>
> >> at this point of time compiler can be sure about what struct is
> >> implementing LCD trait for main.lcd and can bind the function bodies as
> >> compile time, inlining them if applicable.
> >>
> >> This also might be something that is already implemented, please advice.
> >> The goal here is to minimise runtime code being executed and its size.
> >
> >
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-04-08 Thread Vladimir Pouzanov
Awesome use of unreachable!


On Tue, Apr 8, 2014 at 4:53 PM, Peter Marheine  wrote:

> I had a go at building a macro to do this sort of thing, and it turned
> out to be easier than I expected.
>
> https://gist.github.com/tari/10144385
>
> Use like this:
> let x = match_bitfield!(do_something(), bits 4 to 8 {
> 0 => DivideBy1,
> 1 => DivideBy2,
> 2 => DivideBy4,
> _ => UnknownDivisor
> };
>
> On Fri, Apr 4, 2014 at 7:11 AM, Vladimir Pouzanov 
> wrote:
> > I've submitted an RFC for this one:
> > https://github.com/rust-lang/rfcs/pull/29
> >
> >
> > On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers 
> wrote:
> >>
> >> I think the best solution is to add uN and sN types where N is not a
> power
> >> of two, which LLVM should already support.
> >>
> >> Then you can write your match like this:
> >> match (val >> 6) as u2
> >> {
> >>   ...
> >> }
> >>
> >> And it will work as desired.
> >>
> >> Biggest issue is that to make it work nicely you'd need to add some way
> to
> >> generalize over the bit-length and integers, and that's going to require
> >> generics with int parameters and work to add those.
> >>
> >
> >
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>
>
>
> --
> Peter Marheine
> Don't Panic
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Building a static array of pointers

2014-04-05 Thread Vladimir Pouzanov
Ended up specifying array size as per Simon's suggestion:

#[link_section=".isr_vector_temp"]
#[no_mangle]
pub static ISRVectors: [extern unsafe fn(), ..4] = [
  _stack_base,
  main,
  isr_nmi,
  isr_hardfault,
];

Given that table size is an architecture-dependent time constant, it also
adds a tiny bit of verification that all ISRs are defined.

Also tried defining something along the lines of *[extern unsafe fn()], but
I guess size is also required in this case.

Thanks all!



On Sat, Apr 5, 2014 at 12:00 PM, Corey Richardson  wrote:

> A C-style array is written `*T`, much like in C (note: I'm not saying
> `T*` and `T[]` are the same type, I know they aren't)
>
> On Sat, Apr 5, 2014 at 6:53 AM, Simon Sapin  wrote:
> > On 05/04/2014 11:39, Vladimir Pouzanov wrote:
> >>
> >> The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to
> >> the actual array and its size. Is there any way I can get a plain
> >> C-style array in rust?
> >
> >
> > If the size is known as compile-time you can use:
> >
> > static table: [extern unsafe fn(), ..2] = [foo, bar];
> >
> > --
> > Simon Sapin
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
>
>
>
> --
> http://octayn.net/
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Building a static array of pointers

2014-04-05 Thread Vladimir Pouzanov
The problem is that &[extern unsafe fn()] results in 8 bytes, pointer to
the actual array and its size. Is there any way I can get a plain C-style
array in rust?


On Fri, Apr 4, 2014 at 9:06 PM, Alex Crichton  wrote:

> As you've discovered in bug #13325, dealing with external constants in
> static expressions is sometimes a little tricky. I would avoid casting
> for now (as happens in the bug) in favor of stronger types. For
> example, this compiles and runs for me:
>
> extern {
> fn foo();
> fn bar();
> }
>
> static table: &'static [extern unsafe fn()] = &[foo, bar];
>
> pub mod test {
> #[no_mangle] pub extern fn foo() { println!("foo"); }
> #[no_mangle] pub extern fn bar() { println!("bar"); }
> }
>
> fn main() {
> for f in table.iter() {
> unsafe { (*f)(); }
> }
> }
>
> Note that in rust, a value of type `extern fn()` cannot be null, but
> `Option` can indeed be null. You'll probably want
> something along the lines of:
>
> #[link_section = ".isr_vector"]
> pub static ISR_VECTOR_TABLE: [Option, ..N] =
> [Some(...), None, Some(...), ...];
>
> On Fri, Apr 4, 2014 at 12:53 PM, Vladimir Pouzanov 
> wrote:
> > Is it possible to port the following C code to rust?
> >
> > __attribute__ ((section(".isr_vector")))
> > void (* const isr_vector_table[])(void) = {
> > &_stack_base,
> > main, // Reset
> > isr_nmi,  // NMI
> > isr_hardfault,// Hard Fault
> > 0,// CM3 Memory Management Fault
> > 0,// CM3 Bus Fault
> > 0,// CM3 Usage Fault
> > &_boot_checksum,  // NXP Checksum code
> > 0,// Reserved
> > 0,// Reserved
> > 0,// Reserved
> > isr_svcall,   // SVCall
> > 0,// Reserved for debug
> > 0,// Reserved
> > isr_pendsv,   // PendSV
> > isr_systick,  // SysTick
> > };
> >
> > here main and isr_* are rust external functions, and _stack_base is
> defined
> > as
> >
> >   extern void _stack_base()
> >
> > and gets loaded from linker script.
> >
> > Also, is it possible to make a weak symbol in rust or somehow emulate it?
> > Weak symbols are used in C code to provide the following functionality:
> > isr_* functions are stubs with default implementation (morse out id code
> > with led, loop forever), but if any of those requires actual code, than
> it
> > is overrides the weak "morse-blinking" function symbol.
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Building a static array of pointers

2014-04-04 Thread Vladimir Pouzanov
Is it possible to port the following C code to rust?

__attribute__ ((section(".isr_vector")))
void (* const isr_vector_table[])(void) = {
&_stack_base,
main, // Reset
isr_nmi,  // NMI
isr_hardfault,// Hard Fault
0,// CM3 Memory Management Fault
0,// CM3 Bus Fault
0,// CM3 Usage Fault
&_boot_checksum,  // NXP Checksum code
0,// Reserved
0,// Reserved
0,// Reserved
isr_svcall,   // SVCall
0,// Reserved for debug
0,// Reserved
isr_pendsv,   // PendSV
isr_systick,  // SysTick
};

here main and isr_* are rust external functions, and _stack_base is defined
as

  extern void _stack_base()

and gets loaded from linker script.

Also, is it possible to make a weak symbol in rust or somehow emulate it?
Weak symbols are used in C code to provide the following functionality:
isr_* functions are stubs with default implementation (morse out id code
with led, loop forever), but if any of those requires actual code, than it
is overrides the weak "morse-blinking" function symbol.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-04-04 Thread Vladimir Pouzanov
I've submitted an RFC for this one:
https://github.com/rust-lang/rfcs/pull/29


On Sat, Mar 29, 2014 at 6:14 PM, Bill Myers  wrote:

> I think the best solution is to add uN and sN types where N is not a power
> of two, which LLVM should already support.
>
> Then you can write your match like this:
> match (val >> 6) as u2
> {
>   ...
> }
>
> And it will work as desired.
>
> Biggest issue is that to make it work nicely you'd need to add some way to
> generalize over the bit-length and integers, and that's going to require
> generics with int parameters and work to add those.
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting some nesC features to rust?

2014-04-02 Thread Vladimir Pouzanov
If I get it right, calls to traits are resolved in runtime (so, traits are
kind of similar to C++ virtual methods).

What I'm proposing here is a compile-time approach.

Let's say we have the following trait:

pub trait LCD {
  fn line(&mut self, x0_b: i32, y0_b: i32, x1: i32, y1: i32, color: u8);
  fn rect(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: u8);
  fn fillrect(&mut self, x0_b: i32, y0_b: i32, x1_b: i32, y1_b: i32, color:
u8);
  fn putc(&mut self, value: char);
  fn puts(&mut self, s: &str);

  fn flush(&self);
  fn clear(&mut self);
}

which defined a LED screen. There are two structs implementing it: C12832
and ILI9341 (two different lcd controllers).

So I want my app to print hello world on lcd, I write the following code:

  let mut lcd = lcd_c12832::C12832::new(spi);
  let mut l: &mut lcd::LCD = lcd as &mut lcd::LCD;
  l.puts("hello, world");

Which results in a runtime dispatch, a slower and bigger code than the one
I'd have without a trait.

A second problem is there is no easy way to write unified code that
supports both the lcds based on passed in --cfg, as I can't
apply #[cfg(lcd_c12832)] to a chunk of code in fn, and it's kind of
problematic to return a &LCD out from it given that there is no heap and no
analog of placement new from C++.

Proposed binding concept solves those two problems:

#[cfg(lcd_c12832)]
let Binding: binding {
  let lcd: &lcd_c12832::C12832;
  let main: &Main;

  bind main.lcd = lcd;
}

at this point of time compiler can be sure about what struct is
implementing LCD trait for main.lcd and can bind the function bodies as
compile time, inlining them if applicable.

This also might be something that is already implemented, please advice.
The goal here is to minimise runtime code being executed and its size.


On Mon, Mar 31, 2014 at 3:06 PM, Daniel Micay  wrote:

> I'm not really sure exactly what it being proposed here.
>
> Rust's generic types and functions are already entirely expanded at
> compile-time. You *can* use traits as objects for dynamic dispatch, but
> it's not how they're used in the vast majority of cases.
>
>


-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] A new better way to build rust apps

2014-04-01 Thread Vladimir Pouzanov
I decided to switch away from Rakefiles (after I switched to them from
Makefiles) and make a dependency generator / build system in rust to get
20% more coolness factor.

Here's a sample config file:
https://gist.github.com/farcaller/4c08908fe526e0631989. As you can see, the
syntax is somewhat similar to rust code itself, with a few interesting bits
like ~ sigil resolving to 'build' dir and @ sigil resolving to 'src' dir,
so you can use relative paths safely (Rustfiles are all about safety, you
know). It also supports named chainable configurations, so that you can
define all the possible build options in one single file, generics (for
rules expansion) and a background daemon that looks for files being
modified in @ scope to make compilation even faster.

TL;DR: Happy April fools' day :-)

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Porting some nesC features to rust?

2014-03-31 Thread Vladimir Pouzanov
I'd like to propose to extend the language with some concepts from nesC,
which is a nice but quite unknown C superset outside of TinyOS world.

The concept would allow better static polymorphism and better code
optimisations and is loosely based on nesC modules/components. It might be
possible to implement the same in rust without extending the syntax and
compiler, please tell me if that's the case.

unbound struct S {
  reg: u32,
  comp: ~T,
}

defines a struct that has a u32 value and some trait. Those values could be
used in S impls as usual.

It is impossible to create an instance of S, the only way to get it is to
bind it in compile time:

let Binding: binding {
  let SImpl: &S;
  let TImpl: &T;

  bind SImpl.reg = 0x12345678;
  bind SImpl.comp = TImpl;
}

The result of this is that all references to reg and comp are replaced by
actual values (TImpl must obviously be an unbound struct as well), so that
the whole SImpl could be optimised away and don't use any storage bytes
other than required by constants.

Why is it useful? Embedded systems are commonly represented as a tree of
components hooked up to one another. Also, resources on embedded are used
to be expensive. This code allows to define a "configuration" of a system
which is completely resolved in compile time, allowing better optimisation
of the code while maintaining readable code.

Some close-to-real-life example:

unbound struct Led;
impl Led {
  pub fn set_enabled(&self, enabled: bool) {
// set the led state
  }
}

trait Callable {
  fn callback(&self);
}
unbound struct Timer {
  actor: ~Callable,
}
impl Timer {
  pub fn start(&self) {
// init the timer, hardware will call fired() via ISR
  }
  fn fired(&self) {
actor.callback();
  }
}

unbound struct Blinker {
  mut state: bool,
  led: &Led,
  timer: &Timer,
}
impl Callable for Blinker {
  fn callback(&self) {
self.state != self.state;
led.set_enabled(self.state);
  }
}
impl Blinker {
  pub fn main(&self) {
self.timer.start();
  }
}

let Binding: binding {
  let timer = &Timer;
  let led = &Led;
  let blinker = &Blinker { state: false }; // we can also set the mut
property here. This one is static mut by nature, but available only in
Blinker impl.

  bind timer.actor = blinker;
  bind blinker.timer = timer;
  bind blinker.led = led;
}

pub fn main() {
  Binding.blinker.start();
}

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-31 Thread Vladimir Pouzanov
That actually sounds like a good option, thanks!


On Sun, Mar 30, 2014 at 11:22 PM, comex  wrote:

> On Sun, Mar 30, 2014 at 8:08 AM, Vladimir Pouzanov 
> wrote:
> >   gpio::Pin::new(0, 15, gpio::Out, gpio::UART1_TXD); // p13 -> TXD
> >
> > compiles, but something like
> >
> >   gpio::Pin::new(0, 15, gpio::Out, gpio::SPI_MISO); // p13 -> TXD
> >
> > would fail, because there's no SPI_MISO defined for port 0 pin 15.
>
> I would have each port/pin combination be a separate function or
> object which takes an appropriate enum as an argument for the
> function, maybe "fn new_port0_pin15(func: Port0Pin15Func)" or set up
> objects so that "port0.pin15.init(...)" works.  You could use a macro
> to define these more easily.
>
> If you really want to write '(0, 15', you could use a macro to turn
> that into the preceding, but I wouldn't.
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-30 Thread Vladimir Pouzanov
Ok, so I have a number of hardware pins which are defined by port+pin
numbers. Each pin can be connected to different peripheral (e.g. generic
purpose i/o, serial, analog in) which defines it's function.

So, to configure that I have a few u32 registers where each pair of bits
defines a function for a pin, so my configuration function is:

  fn set_mode(port: u8, pin: u8, fun: Function)

You pass in port, pin and it's function, and i/o is being reconfigured
appropriately.

What I have now is this enum:

enum Function {
GPIO = 0,
F1 = 1,
F2 = 2,
F3 = 3,
}

which defines pin's function (function 0 is always GPIO on all the pins,
functions 1-3 are different based on the pin).

Now, in some peripheral init code I write something like:

  gpio::Pin::new(0, 15, gpio::Out, gpio::F1); // p13 -> TXD

and I know that function 1 on port 0 pin 15 is TXD for UART1. I could have
misread the docs and write F2, which would compile, but the code wouldn't
configure the UART pin but do something else, so I want the compiler to
check code for me so that

  gpio::Pin::new(0, 15, gpio::Out, gpio::UART1_TXD); // p13 -> TXD

compiles, but something like

  gpio::Pin::new(0, 15, gpio::Out, gpio::SPI_MISO); // p13 -> TXD

would fail, because there's no SPI_MISO defined for port 0 pin 15.


On Sun, Mar 30, 2014 at 11:41 AM, Simon Sapin  wrote:

> On 30/03/2014 10:30, Vladimir Pouzanov wrote:
>
>> That shifts the issue even more into runtime, doesn't it?
>>
>> My goal is to find a way to resolve a tuple of (u8, u8, FuncNameEnum) to
>> u8, where FuncNameEnum is a long enum of all possible functions. And I
>> need to do that in compile time.
>>
>> One way I see that is to make a really long list of enums like:
>>
>> PORT0_PIN0_GPIO,
>> PORT0_PIN0_RD1,
>> ...
>>
>> for all possible port/pin/function combinations, then I can make a macro
>> to match on that to port/pin/fun u8 (that are actually used to configure
>> registers). The only thing is that I'd like to pass port and pin in as
>> u8 values, that makes it much more readable.
>>
>> Well... Maybe it's time to do some big macro for matching all the stuff
>> and hope that compiler will optimise it anyway.
>>
>
> I’m sorry, it looks like I completely misunderstood your original message.
> But then it’s still not clear to me what you’re trying to do. Could you
> explain in more details, with more context? For example, what is it you
> call a "function"? It seems not to be Rust function declared with the `fn`
> keyword.
>
> --
> Simon Sapin
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Static_assert on a hash

2014-03-30 Thread Vladimir Pouzanov
That shifts the issue even more into runtime, doesn't it?

My goal is to find a way to resolve a tuple of (u8, u8, FuncNameEnum) to
u8, where FuncNameEnum is a long enum of all possible functions. And I need
to do that in compile time.

One way I see that is to make a really long list of enums like:

PORT0_PIN0_GPIO,
PORT0_PIN0_RD1,
...

for all possible port/pin/function combinations, then I can make a macro to
match on that to port/pin/fun u8 (that are actually used to configure
registers). The only thing is that I'd like to pass port and pin in as u8
values, that makes it much more readable.

Well... Maybe it's time to do some big macro for matching all the stuff and
hope that compiler will optimise it anyway.


On Sun, Mar 30, 2014 at 10:12 AM, Simon Sapin  wrote:

> On 30/03/2014 09:50, Vladimir Pouzanov wrote:
>
>> I have a chunk of code that toggles different functions on hardware
>> pins, that looks like this:
>>
>>enum Function {
>>  GPIO = 0,
>>  F1 = 1,
>>  F2 = 2,
>>  F3 = 3,
>>}
>>fn set_mode(port: u8, pin: u8, fun: Function)
>>
>> What I would like to have is an enum of human-readable values instead of
>> F1/F2/F3
>>
>> [...]
>>
>>
>> let fun_idx: u8 = FUNCTIONS[port][pin][fun]
>>
>
>
> I don’t know if you can directly access the static strings for the
> variants’ names behind this, but you can use #[deriving(Show)] to get a
> string representation of any enum value:
>
> For example:
>
> #[deriving(Show)]
>
> enum Function {
> GPIO = 0,
> F1 = 1,
> F2 = 2,
> F3 = 3,
> }
>
> fn main() {
> let f = GPIO;
>
> println!("{:?}", f)
>
> let s: ~str = format!("{:?}", f);
> println!("{}", s)
> }
>
> Output:
>
> GPIO
> GPIO
>
> --
> Simon Sapin
> ___
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Static_assert on a hash

2014-03-30 Thread Vladimir Pouzanov
I have a chunk of code that toggles different functions on hardware pins,
that looks like this:

  enum Function {
GPIO = 0,
F1 = 1,
F2 = 2,
F3 = 3,
  }
  fn set_mode(port: u8, pin: u8, fun: Function)

What I would like to have is an enum of human-readable values instead of
F1/F2/F3, e.g. for port 0, pin 0 I would like to have options of GPIO, RD1,
TXD3, SDA1, for port 0, pin 2 the options would be GPIO, TXD0, AD0.7, - (F3
missing).

I assume it would be possible to have a big enum of function names, that I
would later on map to function index, something like

let fun_idx: u8 = FUNCTIONS[port][pin][fun]

which is what C/C++ developers usually do (
https://github.com/arduino/Arduino/blob/master/hardware/arduino/variants/leonardo/pins_arduino.h--
the thing I don't like about arduino). I would really like to have
this
routing to be done in compile time, as it's just a plain waste of cycles
otherwise. Also, I would like to use static_assert to verify that the
selected function name is actually available for given port/pin combo.

Any ideas?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] matching on a few bits in int

2014-03-28 Thread Vladimir Pouzanov
Sorry, that's definitely a typo, (val >> 6) & 0b11 makes sense, (val &
0b11) >> 6 does not.


On Fri, Mar 28, 2014 at 1:04 PM, Clark Gaebel  wrote:

> I like this! Although I think that match might've been better written
> `(val >> 6) & 0b11`, but it'd be really nice for the compiler to catch
> those type of errors!
>
>   - Clark
>
>
> On Fri, Mar 28, 2014 at 5:54 AM, Vladimir Pouzanov wrote:
>
>> There's one thing that I often have to deal in embedded code — doing
>> match on a few bits from an I/O register, which is commonly u32:
>>
>> let val : u32 = ...;
>> match (val & 0b11) >> 6 {
>>   0b00 => ...,
>>   0b01 => ...,
>>   0b10 => ...,
>>   _ => {}
>> }
>>
>> You can clearly see two problems here: I need to provide a catch-all
>> match, even if the code guarantees a limited set of values; also I lost
>> 0b11, and there's no warning due to catch all.
>>
>> Is it possible to make rustc aware of such cases?
>>
>> What would be totally awesome is some kind of [] operator for ints, that
>> would extract bits, like that:
>>
>> match val[6..7] { ... }
>>
>> Is that something of interest to community? I would be willing to write
>> an RFC for that, and possibly extend the compiler.
>>
>> --
>> Sincerely,
>> Vladimir "Farcaller" Pouzanov
>> http://farcaller.net/
>>
>> ___
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>>
>>
>
>
> --
> Clark.
>
> Key ID : 0x78099922
> Fingerprint: B292 493C 51AE F3AB D016  DD04 E5E3 C36F 5534 F907
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] matching on a few bits in int

2014-03-28 Thread Vladimir Pouzanov
There's one thing that I often have to deal in embedded code — doing match
on a few bits from an I/O register, which is commonly u32:

let val : u32 = ...;
match (val & 0b11) >> 6 {
  0b00 => ...,
  0b01 => ...,
  0b10 => ...,
  _ => {}
}

You can clearly see two problems here: I need to provide a catch-all match,
even if the code guarantees a limited set of values; also I lost 0b11, and
there's no warning due to catch all.

Is it possible to make rustc aware of such cases?

What would be totally awesome is some kind of [] operator for ints, that
would extract bits, like that:

match val[6..7] { ... }

Is that something of interest to community? I would be willing to write an
RFC for that, and possibly extend the compiler.

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
Thanks for links to bugs.

Is there anything to read on the whole morestack thing? I thought that it's
connected to segmented stacks that are (are they?) going away.

It seems that I can use #[no_split_stack] before each and every function to
generate a valid freestanding binary. If I just could use that in header...


On Sun, Mar 23, 2014 at 6:24 PM, Corey Richardson  wrote:

> No. See https://github.com/mozilla/rust/pull/8955 and
> https://github.com/mozilla/rust/issues/11871 for discussion. You can
> stub out
> morestack but that won't remove the stack size checks. It's sanest to
> just compile the IR yourself (the stack checking is a target-specific
> machine pass, which is why it shows up with --emit asm but not --emit
> bc)
>
> On Sun, Mar 23, 2014 at 2:09 PM, Vladimir Pouzanov 
> wrote:
> > So it doesn't work in the end.
> >
> > rustc --emit bc with flags set for cortex-m0 provides exact same bc with
> > only difference in target triple (which makes perfect sense)
> >
> > However, replacing llc step with rustc --emit asm provides a different
> > assembler file, which requires __morestack.
> >
> > Should I expect rustc to generate freestanding code given some additional
> > options?
> >
> >
> > On Sun, Mar 23, 2014 at 5:55 PM, Vladimir Pouzanov 
> > wrote:
> >>
> >> Nevermind, I lost -O somewhere in between copying and pasting command
> line
> >> flags. Optimised version doesn't have any morestack references (which is
> >> strange concept though).
> >>
> >>
> >> On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov  >
> >> wrote:
> >>>
> >>> Figured out I can use --target thumbv6m-linux-eabi, which implies
> >>> -mthumb. Now the problem is that if I use
> >>>
> >>> rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o
> >>>
> >>> instead of three-step process I mentioned before, I get a valid object
> >>> file for cortex-m0, but functions have big prologues and symbol table
> is
> >>> much bigger:
> >>>
> >>>  U STACK_LIMIT
> >>>  U _GLOBAL_OFFSET_TABLE_
> >>>  D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
> >>> 0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
> >>>  r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
> >>> 0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
> >>> 0078 t _ZN4main10__rust_abiE
> >>>  t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
> >>>  U __aeabi_unwind_cpp_pr0
> >>>  U __morestack
> >>> 004c T main
> >>>
> >>> vs.
> >>>
> >>>  D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
> >>>  T main
> >>>
> >>> in the initial version. Also, I now need to provide __morestack (no
> idea
> >>> what's that about).
> >>>
> >>>
> >>> On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton 
> wrote:
> >>>>
> >>>> You should be able to assemble standalone objects for any triple
> >>>> through rustc itself, you'll likely have to specify a different linker
> >>>> or assembler though:
> >>>>
> >>>> rustc foo.rs --target arm-non-linux-gnueabi \
> >>>> -C linker=arm-non-linux-gnueabi-ld \
> >>>> -C ar=arm-non-linux-gnueabi-ar
> >>>>
> >>>> As you discovered, you can pass through arguments to LLVM via the "-C
> >>>> llvm-args=foo" command line option to rustc. If you get complaints
> >>>> that it's an unknown command line argument, it's LLVM telling you
> >>>> those complaints, not rustc.
> >>>>
> >>>> On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov <
> farcal...@gmail.com>
> >>>> wrote:
> >>>> > I'm trying to experiment with rust and some embedded code.
> Currently I
> >>>> > have
> >>>> > to do a three-pass compilation:
> >>>> >
> >>>> > rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
> >>>> > llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
> >>>> > main.s
> >>>> > arm-none-linux-gnueabi-as main.s -o main.o
> >>>> >
> >>>> > First, I'm not sure how relevant i

Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
So it doesn't work in the end.

rustc --emit bc with flags set for cortex-m0 provides exact same bc with
only difference in target triple (which makes perfect sense)

However, replacing llc step with rustc --emit asm provides a different
assembler file, which requires __morestack.

Should I expect rustc to generate freestanding code given some additional
options?


On Sun, Mar 23, 2014 at 5:55 PM, Vladimir Pouzanov wrote:

> Nevermind, I lost -O somewhere in between copying and pasting command line
> flags. Optimised version doesn't have any morestack references (which is
> strange concept though).
>
>
> On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov wrote:
>
>> Figured out I can use --target thumbv6m-linux-eabi, which implies
>> -mthumb. Now the problem is that if I use
>>
>> rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o
>>
>> instead of three-step process I mentioned before, I get a valid object
>> file for cortex-m0, but functions have big prologues and symbol table is
>> much bigger:
>>
>>  U STACK_LIMIT
>>  U _GLOBAL_OFFSET_TABLE_
>>  D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
>> 0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
>>  r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
>> 0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
>> 0078 t _ZN4main10__rust_abiE
>>  t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
>>  U __aeabi_unwind_cpp_pr0
>>  U __morestack
>> 004c T main
>>
>> vs.
>>
>>  D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
>>  T main
>>
>> in the initial version. Also, I now need to provide __morestack (no idea
>> what's that about).
>>
>>
>> On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton  wrote:
>>
>>> You should be able to assemble standalone objects for any triple
>>> through rustc itself, you'll likely have to specify a different linker
>>> or assembler though:
>>>
>>> rustc foo.rs --target arm-non-linux-gnueabi \
>>> -C linker=arm-non-linux-gnueabi-ld \
>>> -C ar=arm-non-linux-gnueabi-ar
>>>
>>> As you discovered, you can pass through arguments to LLVM via the "-C
>>> llvm-args=foo" command line option to rustc. If you get complaints
>>> that it's an unknown command line argument, it's LLVM telling you
>>> those complaints, not rustc.
>>>
>>> On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov 
>>> wrote:
>>> > I'm trying to experiment with rust and some embedded code. Currently I
>>> have
>>> > to do a three-pass compilation:
>>> >
>>> > rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
>>> > llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
>>> main.s
>>> > arm-none-linux-gnueabi-as main.s -o main.o
>>> >
>>> > First, I'm not sure how relevant is --target flag for rustc. I seems to
>>> > change target datalayout/triple in generated bc, but that should be
>>> > overriden by llc -mtriple anyway, right?
>>> >
>>> > Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
>>> > -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
>>> > "rustc: Unknown command line argument '--march=thumb'".
>>> >
>>> > Any hints on how can I drop explicit llc and as steps here?
>>> >
>>> > --
>>> > Sincerely,
>>> > Vladimir "Farcaller" Pouzanov
>>> > http://farcaller.net/
>>> >
>>> > ___
>>> > Rust-dev mailing list
>>> > Rust-dev@mozilla.org
>>> > https://mail.mozilla.org/listinfo/rust-dev
>>> >
>>>
>>
>>
>>
>> --
>> Sincerely,
>> Vladimir "Farcaller" Pouzanov
>> http://farcaller.net/
>>
>
>
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
Nevermind, I lost -O somewhere in between copying and pasting command line
flags. Optimised version doesn't have any morestack references (which is
strange concept though).


On Sun, Mar 23, 2014 at 5:44 PM, Vladimir Pouzanov wrote:

> Figured out I can use --target thumbv6m-linux-eabi, which implies -mthumb.
> Now the problem is that if I use
>
> rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o
>
> instead of three-step process I mentioned before, I get a valid object
> file for cortex-m0, but functions have big prologues and symbol table is
> much bigger:
>
>  U STACK_LIMIT
>  U _GLOBAL_OFFSET_TABLE_
>  D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
> 0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
>  r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
> 0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
> 0078 t _ZN4main10__rust_abiE
>  t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
>  U __aeabi_unwind_cpp_pr0
>  U __morestack
> 004c T main
>
> vs.
>
>  D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
>  T main
>
> in the initial version. Also, I now need to provide __morestack (no idea
> what's that about).
>
>
> On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton  wrote:
>
>> You should be able to assemble standalone objects for any triple
>> through rustc itself, you'll likely have to specify a different linker
>> or assembler though:
>>
>> rustc foo.rs --target arm-non-linux-gnueabi \
>> -C linker=arm-non-linux-gnueabi-ld \
>> -C ar=arm-non-linux-gnueabi-ar
>>
>> As you discovered, you can pass through arguments to LLVM via the "-C
>> llvm-args=foo" command line option to rustc. If you get complaints
>> that it's an unknown command line argument, it's LLVM telling you
>> those complaints, not rustc.
>>
>> On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov 
>> wrote:
>> > I'm trying to experiment with rust and some embedded code. Currently I
>> have
>> > to do a three-pass compilation:
>> >
>> > rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
>> > llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o
>> main.s
>> > arm-none-linux-gnueabi-as main.s -o main.o
>> >
>> > First, I'm not sure how relevant is --target flag for rustc. I seems to
>> > change target datalayout/triple in generated bc, but that should be
>> > overriden by llc -mtriple anyway, right?
>> >
>> > Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
>> > -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
>> > "rustc: Unknown command line argument '--march=thumb'".
>> >
>> > Any hints on how can I drop explicit llc and as steps here?
>> >
>> > --
>> > Sincerely,
>> > Vladimir "Farcaller" Pouzanov
>> > http://farcaller.net/
>> >
>> > ___
>> > Rust-dev mailing list
>> > Rust-dev@mozilla.org
>> > https://mail.mozilla.org/listinfo/rust-dev
>> >
>>
>
>
>
> --
> Sincerely,
> Vladimir "Farcaller" Pouzanov
> http://farcaller.net/
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
Figured out I can use --target thumbv6m-linux-eabi, which implies -mthumb.
Now the problem is that if I use

rustc --target thumbv6m-linux-eabi -O --emit obj main.rs -o main.o

instead of three-step process I mentioned before, I get a valid object file
for cortex-m0, but functions have big prologues and symbol table is much
bigger:

 U STACK_LIMIT
 U _GLOBAL_OFFSET_TABLE_
 D _ZN20_rust_crate_map_main16ad67637f924a5c794v0.0E
0008 r _ZN2hw11GPIO_PIN_NO20hb0b70c1482b61788Gaa4v0.0E
 r _ZN2hw12GPIO_DIR_REG20hb0b70c1482b61788yaa4v0.0E
0004 r _ZN2hw12GPIO_REG_VAL20hb0b70c1482b61788Caa4v0.0E
0078 t _ZN4main10__rust_abiE
 t _ZN4wait20h53ffb23463e08f19Maa4v0.0E
 U __aeabi_unwind_cpp_pr0
 U __morestack
004c T main

vs.

 D _ZN23_rust_crate_map_main.c016ad67637f924a5c794v0.0E
 T main

in the initial version. Also, I now need to provide __morestack (no idea
what's that about).


On Sun, Mar 23, 2014 at 5:17 PM, Alex Crichton  wrote:

> You should be able to assemble standalone objects for any triple
> through rustc itself, you'll likely have to specify a different linker
> or assembler though:
>
> rustc foo.rs --target arm-non-linux-gnueabi \
> -C linker=arm-non-linux-gnueabi-ld \
> -C ar=arm-non-linux-gnueabi-ar
>
> As you discovered, you can pass through arguments to LLVM via the "-C
> llvm-args=foo" command line option to rustc. If you get complaints
> that it's an unknown command line argument, it's LLVM telling you
> those complaints, not rustc.
>
> On Sun, Mar 23, 2014 at 8:54 AM, Vladimir Pouzanov 
> wrote:
> > I'm trying to experiment with rust and some embedded code. Currently I
> have
> > to do a three-pass compilation:
> >
> > rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
> > llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o main.s
> > arm-none-linux-gnueabi-as main.s -o main.o
> >
> > First, I'm not sure how relevant is --target flag for rustc. I seems to
> > change target datalayout/triple in generated bc, but that should be
> > overriden by llc -mtriple anyway, right?
> >
> > Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
> > -march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
> > "rustc: Unknown command line argument '--march=thumb'".
> >
> > Any hints on how can I drop explicit llc and as steps here?
> >
> > --
> > Sincerely,
> > Vladimir "Farcaller" Pouzanov
> > http://farcaller.net/
> >
> > ___
> > Rust-dev mailing list
> > Rust-dev@mozilla.org
> > https://mail.mozilla.org/listinfo/rust-dev
> >
>



-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] How do I pass -march down to llvm from rustc?

2014-03-23 Thread Vladimir Pouzanov
I'm trying to experiment with rust and some embedded code. Currently I have
to do a three-pass compilation:

rustc --target arm-linux-eabi -O --emit bc main.rs -o main.bc
llc -mtriple arm-none-eabi -march=thumb -mcpu=cortex-m0 main.bc -o main.s
arm-none-linux-gnueabi-as main.s -o main.o

First, I'm not sure how relevant is --target flag for rustc. I seems to
change target datalayout/triple in generated bc, but that should be
overriden by llc -mtriple anyway, right?

Second, I can pass -Ctarget-cpu=cortex-m0, but I cannot pass down
-march=thumb, tried this way: -Cllvm-args='--march=thumb', failed with
"rustc: Unknown command line argument '--march=thumb'".

Any hints on how can I drop explicit llc and as steps here?

-- 
Sincerely,
Vladimir "Farcaller" Pouzanov
http://farcaller.net/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev